Як адправіць «шматчастковы/форму-дадзеныя» POST ў Android з Volley

Хто-небудзь быў у стане выканаць адпраўку а Multipart/form-дадзеныя POST ў Android з Volley яшчэ? Я не меў ніякага поспеху спрабуе загрузіць малюнак/PNG з выкарыстаннем запыту POST на наш сервер, і я цікава, калі хтосьці мае.

I believe the default way to do this would be to override public byte[] getPostBody() in the Request.java class and attach the File there with a blank Header key for the boundary. However, converting my file to a String for the Map postParams and then having it encoded again seems obtuse and not really elegant. Also I've been unsuccessful in my attempts. This is really the only thing holding us back from switching to this library.

Ва ўсякім выпадку, усе думкі і адказы надзвычай ацэнены. Дзякуй за дапамогу.

80

9 адказы

I might be wrong on this but I think you need to implement your own com.android.volley.toolbox.HttpStack for this because the default ones (HurlStack if version > Gingerbread or HttpClientStack) don't deal with multipart/form-data.

<�Моцны> Edit:

І на самай справе, я быў няправы. Я быў у стане зрабіць гэта, выкарыстоўваючы MultipartEntity ў запыце, як гэта:

public class MultipartRequest extends Request {

    private MultipartEntity entity = new MultipartEntity();

    private static final String FILE_PART_NAME = "file";
    private static final String STRING_PART_NAME = "text";

    private final Response.Listener mListener;
    private final File mFilePart;
    private final String mStringPart;

    public MultipartRequest(String url, Response.ErrorListener errorListener, Response.Listener listener, File file, String stringPart)
    {
        super(Method.POST, url, errorListener);

        mListener = listener;
        mFilePart = file;
        mStringPart = stringPart;
        buildMultipartEntity();
    }

    private void buildMultipartEntity()
    {
        entity.addPart(FILE_PART_NAME, new FileBody(mFilePart));
        try
        {
            entity.addPart(STRING_PART_NAME, new StringBody(mStringPart));
        }
        catch (UnsupportedEncodingException e)
        {
            VolleyLog.e("UnsupportedEncodingException");
        }
    }

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

    @Override
    public byte[] getBody() throws AuthFailureError
    {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try
        {
            entity.writeTo(bos);
        }
        catch (IOException e)
        {
            VolleyLog.e("IOException writing to ByteArrayOutputStream");
        }
        return bos.toByteArray();
    }

    @Override
    protected Response parseNetworkResponse(NetworkResponse response)
    {
        return Response.success("Uploaded", getCacheEntry());
    }

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

Гэта даволі сырое, але я паспрабаваў яго з выявай і просты радком і яна працуе. Адказ з'яўляецца запаўняльнікам, не мае вялікага сэнсу вяртаць радок адказу ў гэтым выпадку. Я меў праблемы з выкарыстаннем апачского httpmime выкарыстоўваць MultipartEntity таму я выкарыстаў гэтую https://code.google.com/ р/httpclientandroidlib/ не ведаю, калі ёсць лепшы спосаб. Спадзяюся, што гэта дапамагае.

<�Моцны> Edit

Вы можаце выкарыстоўваць httpmime без выкарыстання httpclientandroidlib, адзіная залежнасць з'яўляецца httpcore.

68
дададзена
MultipartEntity гэта прымяншае
дададзена аўтар SpyZip, крыніца
Як мы можам ажыццявіць прагрэс бар для гэтага шматчастковы загрузкі файла? гэта падтрымлівае вялікія файлы? сказаць 100mb!
дададзена аўтар LOG_TAG, крыніца
вярнуцца entity.getContentType() ПолучитьЗначение (). памылка
дададзена аўтар Volodymyr Kulyk, крыніца
Я атрымліваю гэтую памылку: java.lang.NoClassDefFoundError: org.apache.http.entity.ContentType
дададзена аўтар Milad, крыніца
Я павінен быў зрабіць некаторыя нязначныя налады, каб атрымаць гэтую працу за тое, што мне было трэба, але агульная ідэя працавала на 100%. Я збіраўся разрываць ў HurlStack, так што я вельмі рады, што я знайшоў, што гэта загадзя. Дзякуй!
дададзена аўтар zgc7009, крыніца
MultipartEntity з дапамогай Apache HTTP. я хачу зрабіць гэта без апача шматчастковы бібліятэкі. як я магу гэта зрабіць.
дададзена аўтар JosephM, крыніца
@LOG_TAG: Гэта не будзе падтрымліваць вялікія файлы. Не будзе падтрымліваць прагрэс бар. Прычына ў тым, што ён будзе змясціць усе дадзеныя ў адзін байт []. Для вялікіх файлаў, вы хочаце выкарыстоўваць InputStream, які не ўяўляецца магчымым з залпам. Але яны (залпавыя дэвы), а таксама сказаць, што залп не робіцца для вялікіх файлаў.
дададзена аўтар Patrick Boos, крыніца
Вялікі дзякуй за дапамогу! Я буду тэставаць ваша рашэнне заўтра і прыняць яго як правільны адказ, як толькі я магу праверыць.
дададзена аўтар AllDayAmazing, крыніца
@Alex вы можаце змясціць код, як выкарыстоўваць MultipartRequest?
дададзена аўтар Krishna Shrestha, крыніца

Як ужо адзначалася ў выступленні на I/O (каля 04:05), Volley «жудасна" для вялікіх карысных нагрузак. Як я разумею, што значыць не выкарыстоўваць Volley для прыёму/перадачы (вялікія файлы). Гледзячы на ​​кодзе, здаецца, што ён нават не прызначаны для апрацоўкі шматкампанентных дадзеныя формаў (напрыклад Request.java мае getBodyContentType() з жорстка «ужыванне/х-WWW-формаў-urlencoded»; HttpClientStack :: createHttpRequest) можа апрацоўваць (толькі байты [], і г.д ...). Магчыма, вы зможаце стварыць рэалізацыю, якая можа апрацоўваць шматчастковы але калі я вам буду проста выкарыстоўваць HttpClient непасрэдна MultipartEntity як:

    HttpPost req = new HttpPost(composeTargetUrl());
    MultipartEntity entity = new MultipartEntity();
    entity.addPart(POST_IMAGE_VAR_NAME, new FileBody(toUpload));
    try {
        entity.addPart(POST_SESSION_VAR_NAME, new StringBody(uploadSessionId));
    } catch (UnsupportedEncodingException e) {
        throw new RuntimeException(e);
    }
    req.setEntity(entity);

You may need newer HttpClient (i.e. not the built-in) or even better, use Volley with newer HttpClient

13
дададзена
Як я мог мець магчымасць дадаваць іншыя параметры разам з шматчастковы фармаце ў адным запыце?
дададзена аўтар casillas, крыніца
Multipart зараз падтрымліваецца. Паглядзіце на іншыя адказы на гэтай старонцы.
дададзена аўтар Martin Konecny, крыніца
Добры дзень @Ogre_BGR, маглі б вы даць поўны ўзор, як загружаць малюнкі з дапамогай аснасткі вы код. Я паспрабаваў шмат ўзору толькі, але іх вельмі старыя, і я не магу прымусіць яго працаваць. Дзякуй
дададзена аўтар Joolah, крыніца
@MartinKonecny ​​калі ласка, спасылку правільны адказ на ваш каментар, так што іншыя карыстальнікі могуць перайсці непасрэдна да яго
дададзена аўтар Ognyan, крыніца
@casillas entity.addPart (YOUR_OTHER_VAR_NAME, новы StringBody ( "радковае прадстаўленне вашага значэння"));
дададзена аўтар Ognyan, крыніца
Вялікі дзякуй за дапамогу, ваш блог паказвае мне тое, што я б не мець хоць. Я паспрабую ваша прапанова па спасылцы вышэй, калі я не магу атрымаць рашэнне Алекса на працу. Ура!
дададзена аўтар AllDayAmazing, крыніца
Дзякуй сябры, маглі б вы прапанаваць ..what карэкціроўкі, якія я павінен зрабіць для выкарыстання Request.Method.PUT для загрузкі файла малюнка
дададзена аўтар Wish, крыніца
<�Р> Поўны Multipart Запыт з Upload Прагрэс
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.util.CharsetUtils;

import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyLog;
import com.beusoft.app.AppContext;

public class MultipartRequest extends Request {

    MultipartEntityBuilder entity = MultipartEntityBuilder.create();
    HttpEntity httpentity;
    private String FILE_PART_NAME = "files";

    private final Response.Listener mListener;
    private final File mFilePart;
    private final Map mStringPart;
    private Map headerParams;
    private final MultipartProgressListener multipartProgressListener;
    private long fileLength = 0L;

    public MultipartRequest(String url, Response.ErrorListener errorListener,
            Response.Listener listener, File file, long fileLength,
            Map mStringPart,
            final Map headerParams, String partName,
            MultipartProgressListener progLitener) {
        super(Method.POST, url, errorListener);

        this.mListener = listener;
        this.mFilePart = file;
        this.fileLength = fileLength;
        this.mStringPart = mStringPart;
        this.headerParams = headerParams;
        this.FILE_PART_NAME = partName;
        this.multipartProgressListener = progLitener;

        entity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        try {
            entity.setCharset(CharsetUtils.get("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        buildMultipartEntity();
        httpentity = entity.build();
    }

   //public void addStringBody(String param, String value) {
   //if (mStringPart != null) {
   //mStringPart.put(param, value);
   //}
   //}

    private void buildMultipartEntity() {
        entity.addPart(FILE_PART_NAME, new FileBody(mFilePart, ContentType.create("image/gif"), mFilePart.getName()));
        if (mStringPart != null) {
            for (Map.Entry entry : mStringPart.entrySet()) {
                entity.addTextBody(entry.getKey(), entry.getValue());
            }
        }
    }

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

    @Override
    public byte[] getBody() throws AuthFailureError {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            httpentity.writeTo(new CountingOutputStream(bos, fileLength,
                    multipartProgressListener));
        } catch (IOException e) {
            VolleyLog.e("IOException writing to ByteArrayOutputStream");
        }
        return bos.toByteArray();
    }

    @Override
    protected Response parseNetworkResponse(NetworkResponse response) {

        try {
//          System.out.println("Network Response "+ new String(response.data, "UTF-8"));
            return Response.success(new String(response.data, "UTF-8"),
                    getCacheEntry());
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
           //fuck it, it should never happen though
            return Response.success(new String(response.data), getCacheEntry());
        }
    }

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

//Override getHeaders() if you want to put anything in header

    public static interface MultipartProgressListener {
        void transferred(long transfered, int progress);
    }

    public static class CountingOutputStream extends FilterOutputStream {
        private final MultipartProgressListener progListener;
        private long transferred;
        private long fileLength;

        public CountingOutputStream(final OutputStream out, long fileLength,
                final MultipartProgressListener listener) {
            super(out);
            this.fileLength = fileLength;
            this.progListener = listener;
            this.transferred = 0;
        }

        public void write(byte[] b, int off, int len) throws IOException {
            out.write(b, off, len);
            if (progListener != null) {
                this.transferred += len;
                int prog = (int) (transferred * 100/fileLength);
                this.progListener.transferred(this.transferred, prog);
            }
        }

        public void write(int b) throws IOException {
            out.write(b);
            if (progListener != null) {
                this.transferred++;
                int prog = (int) (transferred * 100/fileLength);
                this.progListener.transferred(this.transferred, prog);
            }
        }

    }
}

<�Моцны> Прыклад выкарыстання

protected  void uploadFile(final String tag, final String url,
            final File file, final String partName,         
            final Map headerParams,
            final Response.Listener resultDelivery,
            final Response.ErrorListener errorListener,
            MultipartProgressListener progListener) {
        AZNetworkRetryPolicy retryPolicy = new AZNetworkRetryPolicy();

        MultipartRequest mr = new MultipartRequest(url, errorListener,
                resultDelivery, file, file.length(), null, headerParams,
                partName, progListener);

        mr.setRetryPolicy(retryPolicy);
        mr.setTag(tag);

        Volley.newRequestQueue(this).add(mr);

    }
9
дададзена
Як я мог мець магчымасць дадаваць іншыя параметры разам з шматчастковы фармаце ў адным запыце?
дададзена аўтар casillas, крыніца
Прывітанне @AZ_ - я паспрабаваў ваш код: Але я атрымліваю гэтую памылку: MultipartRequest.getBody: IOException запіс у ByteArrayOutputStream. Вы можаце дапамагчы, калі ласка,
дададзена аўтар Joolah, крыніца
У мяне ёсць Open I новае пытанне: stackoverflow.com/questions/31474585/… вы можаце дапамагчы PLS. Дзякуй
дададзена аўтар Joolah, крыніца
см асабістае Струнны FILE_PART_NAME = «файлы»; у MultiPartRequest вы можаце змяніць яго з вашым патрабаваннем.
дададзена аўтар AZ_, крыніца
@casillas дадаць ключавое значэнне пары ў загаловак запыту.
дададзена аўтар AZ_, крыніца
У мяне няма кода, я нічога не магу прапанаваць лепш, каб адкрыць яшчэ адно пытанне, найбольш верагоднай прычынай можа быць тое, што вы выбеглі з віртуальнай памяці.
дададзена аўтар AZ_, крыніца
@AZ_ Ці можаце вы даць рэальны прыклад? Гэта проста абалонка для канструктара. Мне трэба было, як дадаць файл як парам, як: <�ўвесці імя = тып «FileUpload» = "Файл>
дададзена аўтар Federico Ponzi, крыніца
Ці ёсць спосаб, каб адмяніць пастаянны запыт, як гэта? Калі ласка, звярніцеся да майго пытання: stackoverflow.com/questions/34577601/…
дададзена аўтар John Ernest Guadalupe, крыніца

<�Моцны> UPDATE 2015/08/26:

Калі вы не хочаце выкарыстоўваць састарэлы HttpEntity, вось мой працоўны прыклад кода (пратэставана з ASP.Net WebAPI)

<�Моцны> MultipartActivity.java

package com.example.volleyapp;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.view.Menu;
import android.view.MenuItem;

import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.example.volleyapp.BaseVolleyRequest;
import com.example.volleyapp.VolleySingleton;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;

public class MultipartActivity extends Activity {

    final Context mContext = this;
    String mimeType;
    DataOutputStream dos = null;
    String lineEnd = "\r\n";
    String boundary = "apiclient-" + System.currentTimeMillis();
    String twoHyphens = "--";
    int bytesRead, bytesAvailable, bufferSize;
    byte[] buffer;
    int maxBufferSize = 1024 * 1024;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_multipart);             

        Drawable drawable = ContextCompat.getDrawable(mContext, R.drawable.ic_action_file_attachment_light);
        Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
        final byte[] bitmapData = byteArrayOutputStream.toByteArray();
        String url = "http://192.168.1.100/api/postfile";

        mimeType = "multipart/form-data;boundary=" + boundary;

        BaseVolleyRequest baseVolleyRequest = new BaseVolleyRequest(1, url, new Response.Listener() {
            @Override
            public void onResponse(NetworkResponse response) {

            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        }) {
            @Override
            public String getBodyContentType() {
                return mimeType;
            }

            @Override
            public byte[] getBody() throws AuthFailureError {
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                dos = new DataOutputStream(bos);
                try {
                    dos.writeBytes(twoHyphens + boundary + lineEnd);
                    dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\""
                            + "ic_action_file_attachment_light.png" + "\"" + lineEnd);
                    dos.writeBytes(lineEnd);
                    ByteArrayInputStream fileInputStream = new ByteArrayInputStream(bitmapData);
                    bytesAvailable = fileInputStream.available();

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

                   //read file and write it into form...
                    bytesRead = fileInputStream.read(buffer, 0, bufferSize);

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

                   //send multipart form data necesssary after file data...
                    dos.writeBytes(lineEnd);
                    dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

                    return bos.toByteArray();

                } catch (IOException e) {
                    e.printStackTrace();
                }
                return bitmapData;
            }
        };

        VolleySingleton.getInstance(mContext).addToRequestQueue(baseVolleyRequest);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
       //Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_multipart, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
       //Handle action bar item clicks here. The action bar will
       //automatically handle clicks on the Home/Up button, so long
       //as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

<�Моцны> BaseVolleyRequest.java:

package com.example.volleyapp;

import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.HttpHeaderParser;
import com.google.gson.JsonSyntaxException;


public class BaseVolleyRequest extends Request {

    private final Response.Listener mListener;
    private final Response.ErrorListener mErrorListener;

    public BaseVolleyRequest(String url, Response.Listener listener, Response.ErrorListener errorListener) {
        super(0, url, errorListener);
        this.mListener = listener;
        this.mErrorListener = errorListener;
    }

    public BaseVolleyRequest(int method, String url, Response.Listener listener, Response.ErrorListener errorListener) {
        super(method, url, errorListener);
        this.mListener = listener;
        this.mErrorListener = errorListener;
    }

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

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

    @Override
    protected VolleyError parseNetworkError(VolleyError volleyError) {
        return super.parseNetworkError(volleyError);
    }

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

<�Моцны> END OF UPDATE

Гэта мой працоўны прыклад кода (пратэставаны толькі з файламі невялікага памеру):

public class FileUploadActivity extends Activity {

    private final Context mContext = this;
    HttpEntity httpEntity;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_file_upload);   

        Drawable drawable = getResources().getDrawable(R.drawable.ic_action_home);
        if (drawable != null) {
            Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
            final byte[] bitmapdata = stream.toByteArray();
            String url = "http://10.0.2.2/api/fileupload";
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

           //Add binary body
            if (bitmapdata != null) {
                ContentType contentType = ContentType.create("image/png");
                String fileName = "ic_action_home.png";
                builder.addBinaryBody("file", bitmapdata, contentType, fileName);
                httpEntity = builder.build();

                MyRequest myRequest = new MyRequest(Request.Method.POST, url, new Response.Listener() {
                    @Override
                    public void onResponse(NetworkResponse response) {
                        try {                            
                            String jsonString = new String(response.data,
                                    HttpHeaderParser.parseCharset(response.headers));
                            Toast.makeText(mContext, jsonString, Toast.LENGTH_SHORT).show();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(mContext, error.toString(), Toast.LENGTH_SHORT).show();                        
                    }
                }) {
                    @Override
                    public String getBodyContentType() {
                        return httpEntity.getContentType().getValue();
                    }

                    @Override
                    public byte[] getBody() throws AuthFailureError {
                        ByteArrayOutputStream bos = new ByteArrayOutputStream();
                        try {
                            httpEntity.writeTo(bos);
                        } catch (IOException e) {
                            VolleyLog.e("IOException writing to ByteArrayOutputStream");
                        }
                        return bos.toByteArray();
                    }
                };

                MySingleton.getInstance(this).addToRequestQueue(myRequest);
            }
        }
    }

    ...
}

public class MyRequest extends Request
9
дададзена
Як я магу адаптаваць гэта працаваць з відэа файламі?
дададзена аўтар user3561494, крыніца
Некаторыя серверы вельмі пераборлівыя. Калі ў вас ёсць пытанні, дадаць прабел паміж «;» і «імя файла =" пры стварэнні Content-Disposition і «шматслаёвую/формаў-дадзеных; мяжа =" + мяжа;
дададзена аўтар Kevin, крыніца
@ User3561494 падміргнуў не рэкамендуецца для файлаў вялікага памеру, такіх як відэа
дададзена аўтар BNK, крыніца
Дзякуй за Ваш каментар @Kevin. На самай справе, у мяне не было шмат прыкладанняў сервера, каб праверыць, што :-)
дададзена аўтар BNK, крыніца
@HemsLodha: вазьміце калі ласка зірнуць на адказ RacZo ў ў мяне наступнае пытанне stackoverflow.com/questions/32240177/… , каб убачыць, калі ён можа дапамагчы вам ці не :)
дададзена аўтар BNK, крыніца
Я адпраўляю пост шматслойнага запыт з залпам і, нарэшце, усталяваць параметр ў URL-адрас, і яна працуе. Дзякуй за дапамогу @BNK.
дададзена аўтар JosephM, крыніца
Як я магу дадаць іншы параметр з файлам як CUSTOMERID і г.д ..
дададзена аўтар JosephM, крыніца

Вельмі просты падыход для распрацоўніка, які проста трэба адправіць параметры POST ў шматчастковы запыце.

<�Р> Унесці наступныя змяненні ў класе, які праходзіць Request.java

Спачатку вызначым гэтыя канстанты:

String BOUNDARY = "s2retfgsGSRFsERFGHfgdfgw734yhFHW567TYHSrf4yarg"; //This the boundary which is used by the server to split the post parameters.
String MULTIPART_FORMDATA = "multipart/form-data;boundary=" + BOUNDARY;

Дадайце дапаможную функцыю, каб стварыць пост цела для вас:

private String createPostBody(Map params) {
        StringBuilder sbPost = new StringBuilder();
        if (params != null) {
            for (String key : params.keySet()) {
                if (params.get(key) != null) {
                    sbPost.append("\r\n" + "--" + BOUNDARY + "\r\n");
                    sbPost.append("Content-Disposition: form-data; name=\"" + key + "\"" + "\r\n\r\n");
                    sbPost.append(params.get(key).toString());
                }
            }
        }
        return sbPost.toString();
    } 

Пераазначэнне getBody() і getBodyContentType

public String getBodyContentType() {
    return MULTIPART_FORMDATA;
}

public byte[] getBody() throws AuthFailureError {
        return createPostBody(getParams()).getBytes();
}
5
дададзена
@Arpit дзякуй, я быў у стане вырашыць маю праблему з дапамогай гэтага дапаможнага класа замест сутнасці .github.com/anggadarkprince/& hellip;
дададзена аўтар Woppi, крыніца
Дзякуй! Гэта працуе для мяне на пярэднім канцы, але фонавы спецыяльна nodejs паўсталі праблемы пры разборы яго? Вы выпрабоўваеце якія-небудзь з гэтага?
дададзена аўтар Woppi, крыніца
Вельмі проста і выдатна працуе! Я павінен быў sbPost.append ( «-» + МЯЖЫ + «-»); прама перад тым, як ён можа вярнуцца з API, я выкарыстоўваю патрабуе які зачыняе тэга
дададзена аўтар Sirens, крыніца
На жаль у мяне няма вопыту бэкэнда :(
дададзена аўтар Arpit Ratan, крыніца
Вялікі дзякуй :)
дададзена аўтар Arpit Ratan, крыніца

Першы адказ на SO.

Я сутыкаўся з такой жа праблемай і знайшоў @Alex «s код вельмі карысна. Я зрабіў некалькі простых змяненняў, каб прайсці як шмат параметраў, па меры неабходнасці праз HashMap, і ў асноўным скапіяваныя parseNetworkResponse() з StringRequest. Я шукаў у Інтэрнэце і так здзіўлены, выявіўшы, што такая агульная задача так рэдка адказвала. Ва ўсякім выпадку, я жадаю код можа дапамагчы:

public class MultipartRequest extends Request {

private MultipartEntity entity = new MultipartEntity();

private static final String FILE_PART_NAME = "image";

private final Response.Listener mListener;
private final File file;
private final HashMap params;

public MultipartRequest(String url, Response.Listener listener, Response.ErrorListener errorListener, File file, HashMap params)
{
    super(Method.POST, url, errorListener);

    mListener = listener;
    this.file = file;
    this.params = params;
    buildMultipartEntity();
}

private void buildMultipartEntity()
{
    entity.addPart(FILE_PART_NAME, new FileBody(file));
    try
    {
        for ( String key : params.keySet() ) {
            entity.addPart(key, new StringBody(params.get(key)));
        }
    }
    catch (UnsupportedEncodingException e)
    {
        VolleyLog.e("UnsupportedEncodingException");
    }
}

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

@Override
public byte[] getBody() throws AuthFailureError
{
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    try
    {
        entity.writeTo(bos);
    }
    catch (IOException e)
    {
        VolleyLog.e("IOException writing to ByteArrayOutputStream");
    }
    return bos.toByteArray();
}

/**
 * copied from Android StringRequest class
 */
@Override
protected Response parseNetworkResponse(NetworkResponse response) {
    String parsed;
    try {
        parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
    } catch (UnsupportedEncodingException e) {
        parsed = new String(response.data);
    }
    return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
}

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

І вы можаце выкарыстоўваць клас наступным чынам:

    HashMap params = new HashMap();

    params.put("type", "Some Param");
    params.put("location", "Some Param");
    params.put("contact",  "Some Param");


    MultipartRequest mr = new MultipartRequest(url, new Response.Listener(){

        @Override
        public void onResponse(String response) {
            Log.d("response", response);
        }

    }, new Response.ErrorListener(){

        @Override
        public void onErrorResponse(VolleyError error) {
            Log.e("Volley Request Error", error.getLocalizedMessage());
        }

    }, f, params);

    Volley.newRequestQueue(this).add(mr);
4
дададзена
ён павінен быць прыняты адказам .... дзякуй шмат Майкла
дададзена аўтар GvSharma, крыніца

Гэта мой спосаб зрабіць гэта. Гэта можа быць карысна іншым:

private void updateType(){
   //Log.i(TAG,"updateType");
     StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener() {

         @Override
         public void onResponse(String response) {
            //running on main thread-------
             try {
                 JSONObject res = new JSONObject(response);
                 res.getString("result");
                 System.out.println("Response:" + res.getString("result"));

                 }else{
                     CustomTast ct=new CustomTast(context);
                     ct.showCustomAlert("Network/Server Disconnected",R.drawable.disconnect);
                 }

             } catch (Exception e) {
                 e.printStackTrace();

                 //Log.e("Response", "==> " + e.getMessage());
             }
         }
     }, new Response.ErrorListener() {
         @Override
         public void onErrorResponse(VolleyError volleyError) {
            //running on main thread-------
             VolleyLog.d(TAG, "Error: " + volleyError.getMessage());

         }
     }) {
         protected Map getParams() {
             HashMap hashMapParams = new HashMap();
             hashMapParams.put("key", "value");
             hashMapParams.put("key", "value");
             hashMapParams.put("key", "value"));
             hashMapParams.put("key", "value");
             System.out.println("Hashmap:" + hashMapParams);
             return hashMapParams;
         }
     };
     AppController.getInstance().addToRequestQueue(request);

 }
2
дададзена

Вось простае рашэнне, і Скончаны прыклад для загрузкі файлаў з дапамогай Volley Android

1) Gradle Імпарт

compile 'dev.dworks.libs:volleyplus:+'

2) Зараз Стварыце RequestManager класа

public class RequestManager {
    private static RequestManager mRequestManager;
    /**
     * Queue which Manages the Network Requests :-)
     */
    private static RequestQueue mRequestQueue;
   //ImageLoader Instance

    private RequestManager() {

    }

    public static RequestManager get(Context context) {

        if (mRequestManager == null)
            mRequestManager = new RequestManager();

        return mRequestManager;
    }

    /**
     * @param context application context
     */
    public static RequestQueue getnstance(Context context) {

        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(context);
        }

        return mRequestQueue;

    }


}

3) Зараз створым клас для апрацоўкі запыту для загрузкі файла WebService

public class WebService {
    private RequestQueue mRequestQueue;
    private static WebService apiRequests = null;

    public static WebService getInstance() {
        if (apiRequests == null) {
            apiRequests = new WebService();
            return apiRequests;
        }
        return apiRequests;
    }
    public void updateProfile(Context context, String doc_name, String doc_type, String appliance_id, File file, Response.Listener listener, Response.ErrorListener errorListener) {
        SimpleMultiPartRequest request = new SimpleMultiPartRequest(Request.Method.POST, "YOUR URL HERE", listener, errorListener);
//        request.setParams(data);
        mRequestQueue = RequestManager.getnstance(context);
        request.addMultipartParam("token", "text", "tdfysghfhsdfh");
        request.addMultipartParam("parameter_1", "text", doc_name);
        request.addMultipartParam("dparameter_2", "text", doc_type);
        request.addMultipartParam("parameter_3", "text", appliance_id);
            request.addFile("document_file", file.getPath());

        request.setFixedStreamingMode(true);
        mRequestQueue.add(request);
    }
}

4) А цяпер выклікае метад Like This Хіт службы

public class Main2Activity extends AppCompatActivity implements Response.ErrorListener, Response.Listener{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        Button button=(Button)findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                uploadData();
            }
        });
    }

    private void uploadData() {
        WebService.getInstance().updateProfile(getActivity(), "appl_doc", "appliance", "1", mChoosenFile, this, this);
    }

    @Override
    public void onErrorResponse(VolleyError error) {

    }

    @Override
    public void onResponse(String response) {
     //Your response here 
    }
}
0
дададзена
Я выкарыстаў адзін раз, апісаны тут і ваш адказ github.com/DWorkS/VolleyPlus
дададзена аўтар SpyZip, крыніца
Я атрымліваю гэтую памылку з вашым рашэннем: java.lang.NoSuchMethodError: Няма прамога метаду (ILjava/мовы/String; Lcom/Android/залп/Request $ Priori & ZWNJ; ці; Lcom/Android/Фоллю & ZWNJ; еу/адказ $ ErrorLis & ZWNJ; Tener; Lcom/Android/пра & ZWNJ; Olley/RetryPolicy;) V у класе LCOM/Android/залпавага/запыт; або яго супер-класа (Дэкларацыя з'яўляецца '' com.android.volley.Request ў /data/data/com.footballscout.app/files/instant-run/dex/slice‌ -slice_4-classes.dex & ZWNJ;)
дададзена аўтар SpyZip, крыніца
і праверыць імпарт у класе, дзе калі-небудзь у выкарыстоўвае, таму што вы не павінны выкарыстоўваць правільны імпарт для залпу, як памылка ўказвае на слухача памылкі, праверыць імпарт зноў і Gradle затым ачысціць праект, дзякуй, калі і да гэтага часу знайсці якую-небудзь праблема, дайце мне ведаць,
дададзена аўтар quick learner, крыніца
Вы праверыць правільнасць Gradle і імпарту ў класах?
дададзена аўтар quick learner, крыніца

Іншае рашэнне, вельмі лёгкі з высокай прадукцыйнасцю з карыснай нагрузкай вялікі:

Android Asynchronous Http Client library: http://loopj.com/android-async-http/

private static AsyncHttpClient client = new AsyncHttpClient();

private void uploadFileExecute(File file) {

    RequestParams params = new RequestParams();

    try { params.put("photo", file); } catch (FileNotFoundException e) {}

    client.post(getUrl(), params,

        new AsyncHttpResponseHandler() {

            public void onSuccess(String result) {

                Log.d(TAG,"uploadFile response: "+result);

            };

            public void onFailure(Throwable arg0, String errorMsg) {

                Log.d(TAG,"uploadFile ERROR!");

            };

        }

    );

}
0
дададзена
@Ravi +1 гэтая бібліятэка смокча для загрузкі вялікіх файлаў
дададзена аўтар Anton, крыніца
вялікія памеры файлаў выдаюць выключэнне памяці
дададзена аўтар Ravi, крыніца
калі вы хочаце адправіць вялікія файлы з дапамогай Apache бібліятэкі пантамімы для шматгалосныя, а затым адправіць яго з дапамогай гэтай бібліятэкі.
дададзена аўтар Ravi, крыніца
Вам трэба сціснуць памер малюнка, а затым выкарыстоўваць гэтую бібліятэку, каб загрузіць файл я знайшоў рашэнне знізу URL: programmerguru.com/android-tutorial/&hellip, Я спадзяюся, што гэта можа зэканоміць час кагосьці.
дададзена аўтар Milan Sheth, крыніца