Как опубликовать аудио и изображение в виде multipart/formdata в родном Android?

Я хочу опубликовать данные формы следующим образом,

введите здесь описание изображения

куда,

  1. ApiKey, идентификатор пользователя, альбом, имя_музыки, имя_певца — это ключи, соответствующие значения которых имеют текстовый тип.
  2. music_cover и music_file являются ключами для файла изображения и аудиофайла в качестве их значения.

Все значения не могут принимать значения NULL. То есть необходимо передать все значения на сервер, чтобы получить ответ об успешном завершении.

Итак, в общем, у меня есть куча текстов, аудио и изображения для загрузки на сервер с помощью веб-сервиса с Android.

Я выбираю изображение и звук с помощью средства выбора, поэтому у меня есть путь к их файлу.

Пожалуйста, проведите меня через процесс загрузки аудио и изображения с помощью multipart с Android.

Это не давало мне спать всю ночь, и все же нет передышки.


person Bodhisatwa Chakraborty    schedule 29.05.2018    source источник


Ответы (1)


Здесь я создал пример, используя Volley. Итак, прежде всего, мы должны построить RestApiMultiPartRequests.class, поэтому здесь я создал его следующим образом.

частный класс RestApiMultiPartRequests расширяет запрос {

private final Map<String, String> mStringParts;
private final Map<String, File> mFileParts;
private MultipartEntityBuilder mBuilder;
private final Response.Listener<T> mListener;

public RestApiMultiPartRequests(String url,
                                Map<String, String> stringParts,
                                Map<String, File> fileParts,
                                Response.Listener<T> listener,
                                Response.ErrorListener errorListener) {
    super(Method.POST, url, errorListener);
    mListener = listener;
    mStringParts = stringParts;
    mFileParts = fileParts;
    buildMultipartEntity();
}

private void buildMultipartEntity() {
    if (mBuilder != null) {
        mBuilder = null;
    }
    mBuilder = MultipartEntityBuilder.create();
    mBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
    mBuilder.setBoundary("_____" + Long.toString(System.currentTimeMillis()) + "_____");
    mBuilder.setCharset(Consts.UTF_8);
    if (mStringParts != null) {
        for (Map.Entry<String, String> entry : mStringParts.entrySet()) {
            mBuilder.addTextBody(entry.getKey(), entry.getValue(), ContentType.create("text/plain", Charset.forName("UTF-8")));
        }
    }

    Log.e("Size", "Size: " + mFileParts.size());
    for (Map.Entry<String, File> entry : mFileParts.entrySet()) {
        ContentType imageContentType = ContentType.create("image/*");//MULTIPART_FORM_DATA;
        Log.d("", "Key " + entry.getKey());
        Log.d("", "Value " + entry.getValue());
        Log.d("", "Name " + entry.getValue().getName());
        //"userfile"
        mBuilder.addBinaryBody(entry.getKey(), entry.getValue(), imageContentType, entry.getValue().getName());
    }
}

@Override
public String getBodyContentType() {
    return mBuilder.build().getContentType().getValue();
}

@Override
public byte[] getBody() {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    try {
        mBuilder.build().writeTo(bos);
    } catch (IOException e) {
        e.printStackTrace();
    }

    return bos.toByteArray();
}


public HttpEntity getEntity() {
    return mBuilder.build();
}


@SuppressWarnings("unchecked")
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
    try {
        String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
        return (Response<T>) Response.success(jsonString, HttpHeaderParser.parseCacheHeaders(response));
    } catch (UnsupportedEncodingException e) {
        return Response.error(new ParseError(e));
    }
}

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

}


}

Используя этот класс, мы можем создать такой запрос

 private void UploadImage() {

    ServiceCall.RestApiMultiPartRequests<String> restApiMultiPartRequest =
            new ServiceCall.RestApiMultiPartRequests<String>(url/*YOUR SERVICE URL*/, hashMap /* HASHMAP OF STRING */, fileparts  /*HASH MAP OF FILE AND STRING */, new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                   /*   HANDEL YOUR SUCCESS RESPONSE **/
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    // Handle your error types accordingly.For Timeout & No
                    // connection error, you can show 'retry' button.
                    // For AuthFailure, you can re login with user
                    // credentials.
                    // For ClientError, 400 & 401, Errors happening on
                    // client side when sending api request.
                    // In this case you can check how client is forming the
                    // api and debug accordingly.
                    // For ServerError 5xx, you can do retry or handle
                    // accordingly.


                      /**  HANDLE YOUR ERRORS */
                }
            }) {

                @Override
                public Map<String, String> getHeaders() throws AuthFailureError {
                    Map<String, String> params = new HashMap<String, String>();
                    params.put("Authorization","YOUR AUTHANTICATION TOKEN IF REQUIRED");
                    return params;
                }

                @Override
                protected Map<String, String> getParams() throws AuthFailureError {
                    Map<String, String> params = new HashMap<String, String>();
                    return params;
                }
            };

    restApiMultiPartRequest.setRetryPolicy(new DefaultRetryPolicy(0, 1, 2));//10000
    VOLLEY_INSTANCE.addToRequestQueue(restApiMultiPartRequest);
}

Здесь hashmap это HashMap<String, String> hashMap, а fileparts это HashMap<String, File> fileparts;

поэтому параметры с String key и String value добавляются к hashmap, а параметры с ключом String и File Value добавляются к fileparts

person Jay Thummar    schedule 29.05.2018
comment
Я застрял с MultipartEntityBuilder. Не удалось найти его в проекте Android. Почему я получаю ошибку в связанных строках? - person Bodhisatwa Chakraborty; 29.05.2018
comment
И что такое Т в Response‹T›?? - person Bodhisatwa Chakraborty; 29.05.2018
comment
извините, я забыл сказать вам, что для этого вам нужно добавить библиотеку useLibrary 'org.apache.http.legacy', добавить вот так android { compileSdkVersion 27 useLibrary 'org.apache.http.legacy' defaultConfig { applicationId PACKAGE minSdkVersion 15 targetSdkVersion 27 versionCode 1 versionName 1.0 testInstrumentationRunner android.support.test.runner.AndroidJUnitRunner } - person Jay Thummar; 29.05.2018
comment
зависимости { группа реализации: 'org.apache.httpcomponents', имя: 'httpclient-android', версия: '4.3.5.1' реализация ('org.apache.httpcomponents:httpmime:4.3') { модуль исключения: httpclient } } - person Jay Thummar; 29.05.2018
comment
добавить это в градель - person Jay Thummar; 29.05.2018
comment
ServiceCall.RestApiMultiPartRequests‹String› restApiMultiPartRequests = new ServiceCall.RestApiMultiPartRequests‹String›(url/*URL ВАШЕЙ СЛУЖБЫ*/, hashMap /* HASHMAP OF STRING */, fileparts /*HASH MAP OF FILE AND STRING */, new Response.Listener ‹String›() {} -› кроме части URL... как хэш-карта, так и файловые части мне неясны. Что и как передать эти два аргумента относительно ключей, которые мне нужно передать в данных формы, как показано на скриншоте - person Bodhisatwa Chakraborty; 29.05.2018
comment
Давайте продолжим это обсуждение в чате. - person Bodhisatwa Chakraborty; 29.05.2018
comment
Спасибо Джей! Мне просто нужно было немного изменить код Lil в предоставленном вами ответе и вуаля! Готово! - person Bodhisatwa Chakraborty; 30.05.2018