Post Multipart Anfrage mit Android SDK

79

Ich versuche etwas zu tun, von dem ich dachte, dass es relativ einfach ist: Laden Sie ein Bild mit dem Android SDK auf einen Server hoch. Ich habe viel Beispielcode gefunden:

http://groups.google.com/group/android-developers/browse_thread/thread/f9e17bbaf50c5fc/46145fcacd450e48

http://linklens.blogspot.com/2009/06/android-multipart-upload.html

Aber keine Arbeit für mich. Die Verwirrung, auf die ich immer wieder stoße, ist das, was wirklich benötigt wird, um eine mehrteilige Anfrage zu stellen. Was ist der einfachste Weg, um einen mehrteiligen Upload (mit einem Bild) für Android durchzuführen?

Jede Hilfe oder Beratung wäre sehr dankbar!

jpoz
quelle
Was sind die Probleme, die Sie mit den Methoden haben, die Sie bisher ausprobiert haben?
Christopher Orr
1
Oh viele Probleme. Derzeit wird die Foto-URL von der Fotoauswahl in eine Datei zurückgegeben, die ich an eine MultipartEntity anhängen kann. Ich bin mir jedoch nicht einmal sicher, ob dies der richtige Weg ist, um eine Multiport-Anfrage zu erstellen.
jpoz

Antworten:

103

Update 29. April 2014:

Meine Antwort ist mittlerweile ziemlich alt und ich denke, Sie möchten lieber eine Bibliothek auf hoher Ebene wie Retrofit verwenden .


Basierend auf diesem Blog habe ich die folgende Lösung gefunden: http://blog.tacticalnuclearstrike.com/2010/01/using-multipartentity-in-android-applications/

Sie müssen zusätzliche Bibliotheken herunterladen, um loszulegen MultipartEntity!

1) Laden Sie httpcomponents-client-4.1.zip von http://james.apache.org/download.cgi#Apache_Mime4J herunter und fügen Sie Ihrem Projekt apache-mime4j-0.6.1.jar hinzu.

2) Laden Sie httpcomponents-client-4.1-bin.zip von http://hc.apache.org/downloads.cgi herunter und fügen Sie Ihrem Projekt httpclient-4.1.jar, httpcore-4.1.jar und httpmime-4.1.jar hinzu.

3) Verwenden Sie den folgenden Beispielcode.

private DefaultHttpClient mHttpClient;


public ServerCommunication() {
    HttpParams params = new BasicHttpParams();
    params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
    mHttpClient = new DefaultHttpClient(params);
}


public void uploadUserPhoto(File image) {

    try {

        HttpPost httppost = new HttpPost("some url");

        MultipartEntity multipartEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);  
        multipartEntity.addPart("Title", new StringBody("Title"));
        multipartEntity.addPart("Nick", new StringBody("Nick"));
        multipartEntity.addPart("Email", new StringBody("Email"));
        multipartEntity.addPart("Description", new StringBody(Settings.SHARE.TEXT));
        multipartEntity.addPart("Image", new FileBody(image));
        httppost.setEntity(multipartEntity);

        mHttpClient.execute(httppost, new PhotoUploadResponseHandler());

    } catch (Exception e) {
        Log.e(ServerCommunication.class.getName(), e.getLocalizedMessage(), e);
    }
}

private class PhotoUploadResponseHandler implements ResponseHandler<Object> {

    @Override
    public Object handleResponse(HttpResponse response)
            throws ClientProtocolException, IOException {

        HttpEntity r_entity = response.getEntity();
        String responseString = EntityUtils.toString(r_entity);
        Log.d("UPLOAD", responseString);

        return null;
    }

}
vinzenzweber
quelle
4
Ich kann die MultipartEntity- und die HttpMultipartClient-Bibliothek in Android nicht finden. Kannst du mir bitte helfen?
Nguyen Minh Binh
23
Das ist die richtige Antwort. Schade, dass diese Klasse nicht im Android SDK enthalten ist.
Moonlightcheese
2
Warum brauchen Sie apache-mime4j-0.6.1.jar?
JPM
5
Jeder, der nach diesem ersten Satz von Dateien sucht, ist jetzt hier: psg.mtu.edu/pub/apache//james/mime4j
Keeano
5
Danke für die Lösung. Allerdings MultipartEntityist jetzt veraltet. Dieser Beitrag kann diejenigen führen, die MultipartEntityBuilderstattdessen verwenden möchten
Sufian
47

Da MultiPartEntityist veraltet . Also hier ist der neue Weg, es zu tun! Und Sie brauchen sie nur httpcore.jar(latest)und httpmime.jar(latest)laden sie von der Apache-Site herunter.

try
{
    HttpClient client = new DefaultHttpClient();
    HttpPost post = new HttpPost(URL);

    MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
    entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

    entityBuilder.addTextBody(USER_ID, userId);
    entityBuilder.addTextBody(NAME, name);
    entityBuilder.addTextBody(TYPE, type);
    entityBuilder.addTextBody(COMMENT, comment);
    entityBuilder.addTextBody(LATITUDE, String.valueOf(User.Latitude));
    entityBuilder.addTextBody(LONGITUDE, String.valueOf(User.Longitude));

    if(file != null)
    {
        entityBuilder.addBinaryBody(IMAGE, file);
    }

    HttpEntity entity = entityBuilder.build();
    post.setEntity(entity);
    HttpResponse response = client.execute(post);
    HttpEntity httpEntity = response.getEntity();
    result = EntityUtils.toString(httpEntity);
    Log.v("result", result);
}
catch(Exception e)
{
    e.printStackTrace();
}
Muhammad Babar
quelle
1
+1 für die Verwendung des Builders, da die direkte Instanziierung veraltet ist.
Npace
Diese Antwort hat mir eine Menge Zeit gespart. Vielen Dank!
PearsonArtPhoto
@ Muhammad Babar Kannst du mir sagen, wie ich mehrere Bilder mit hochladen möchte MultipartEntityBuilder?
Menma
innerhalb einer Schleife und stellen Sie dann entityBuilder.addBinaryBody(key, file);sicher, dass der Schlüssel eindeutig ist.
Muhammad Babar
16
Verwenden Sie compile 'org.apache.httpcomponents: httpmime: 4.3.4' compile 'org.apache.httpcomponents: httpcore: 4.3.2' für Android Studio-Abhängigkeiten
Tyler Davis
15

Hier ist die LIGHT WEIGHTED-Lösung, die für mich ohne externen HTTPCore und solche Bibliotheken funktioniert hat. Ich hatte Probleme mit 64K-Methoden, daher habe ich keine Option mehr, um HTTPCore-Bibliotheken zu vermeiden

import java.util.List;

import java.io.BufferedReader;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

/**
 * This utility class provides an abstraction layer for sending multipart HTTP
 * POST requests to a web server.
 *
 * @author www.codejava.net
 */
public class MultipartUtility {
    private final String boundary;
    private static final String LINE_FEED = "\r\n";
    private HttpURLConnection httpConn;
    private String charset;
    private OutputStream outputStream;
    private PrintWriter writer;

    /**
     * This constructor initializes a new HTTP POST request with content type
     * is set to multipart/form-data
     *
     * @param requestURL
     * @param charset
     * @throws IOException
     */
    public MultipartUtility(String requestURL, String charset)
            throws IOException {
        this.charset = charset;

        // creates a unique boundary based on time stamp
        boundary = "===" + System.currentTimeMillis() + "===";

        URL url = new URL(requestURL);
        httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setUseCaches(false);
        httpConn.setDoOutput(true); // indicates POST method
        httpConn.setDoInput(true);
        httpConn.setRequestProperty("Content-Type",
                "multipart/form-data; boundary=" + boundary);
        httpConn.setRequestProperty("User-Agent", "CodeJava Agent");
        httpConn.setRequestProperty("Test", "Bonjour");
        outputStream = httpConn.getOutputStream();
        writer = new PrintWriter(new OutputStreamWriter(outputStream, charset),
                true);
    }

    /**
     * Adds a form field to the request
     *
     * @param name  field name
     * @param value field value
     */
    public void addFormField(String name, String value) {
        writer.append("--" + boundary).append(LINE_FEED);
        writer.append("Content-Disposition: form-data; name=\"" + name + "\"")
                .append(LINE_FEED);
        writer.append("Content-Type: text/plain; charset=" + charset).append(
                LINE_FEED);
        writer.append(LINE_FEED);
        writer.append(value).append(LINE_FEED);
        writer.flush();
    }

    /**
     * Adds a upload file section to the request
     *
     * @param fieldName  name attribute in <input type="file" name="..." />
     * @param uploadFile a File to be uploaded
     * @throws IOException
     */
    public void addFilePart(String fieldName, File uploadFile)
            throws IOException {
        String fileName = uploadFile.getName();
        writer.append("--" + boundary).append(LINE_FEED);
        writer.append(
                "Content-Disposition: form-data; name=\"" + fieldName
                        + "\"; filename=\"" + fileName + "\"")
                .append(LINE_FEED);
        writer.append(
                "Content-Type: "
                        + URLConnection.guessContentTypeFromName(fileName))
                .append(LINE_FEED);
        writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
        writer.append(LINE_FEED);
        writer.flush();

        FileInputStream inputStream = new FileInputStream(uploadFile);
        byte[] buffer = new byte[4096];
        int bytesRead = -1;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }
        outputStream.flush();
        inputStream.close();

        writer.append(LINE_FEED);
        writer.flush();
    }

    /**
     * Adds a header field to the request.
     *
     * @param name  - name of the header field
     * @param value - value of the header field
     */
    public void addHeaderField(String name, String value) {
        writer.append(name + ": " + value).append(LINE_FEED);
        writer.flush();
    }

    /**
     * Completes the request and receives response from the server.
     *
     * @return a list of Strings as response in case the server returned
     * status OK, otherwise an exception is thrown.
     * @throws IOException
     */
    public List<String> finish() throws IOException {
        List<String> response = new ArrayList<String>();

        writer.append(LINE_FEED).flush();
        writer.append("--" + boundary + "--").append(LINE_FEED);
        writer.close();

        // checks server's status code first
        int status = httpConn.getResponseCode();
        if (status == HttpURLConnection.HTTP_OK) {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    httpConn.getInputStream()));
            String line = null;
            while ((line = reader.readLine()) != null) {
                response.add(line);
            }
            reader.close();
            httpConn.disconnect();
        } else {
            throw new IOException("Server returned non-OK status: " + status);
        }

        return response;
    }
}

VERWENDUNG

private void uploadMedia() {
        try {

            String charset = "UTF-8";
            File uploadFile1 = new File("/sdcard/myvideo.mp4");
            String requestURL = Data.BASE_URL+Data.URL_UPLOAD_REACTION_TEST;

            MultipartUtility multipart = new MultipartUtility(requestURL, charset);

//            multipart.addHeaderField("User-Agent", "CodeJava");
//            multipart.addHeaderField("Test-Header", "Header-Value");

            multipart.addFormField("friend_id", "Cool Pictures");
            multipart.addFormField("userid", "Java,upload,Spring");

            multipart.addFilePart("uploadedfile", uploadFile1);

            List<String> response = multipart.finish();

            Log.v("rht", "SERVER REPLIED:");

            for (String line : response) {
                Log.v("rht", "Line : "+line);

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

    }

PHP-Code zum Akzeptieren des Uploads

<?php

    $friend_id = $_REQUEST['friend_id'];
    $userid = $_REQUEST['userid'];

    echo 'friend_id : '.$friend_id. ' userid '.$userid;

    move_uploaded_file($_FILES['uploadedfile']['tmp_name'], "./uploads/".$_FILES["uploadedfile"]["name"]);

?>
Rohit Mandiwal
quelle
Für diese Grenze warf mein Code 400 Bad Request border = "===" + System.currentTimeMillis () + "==="; Dann habe ich die Grenze geändert als border = "---" + System.currentTimeMillis (); Dann wurde die Anfrage im Backend richtig analysiert.
Prashant
warum ist das so kompliziert ...? Nein genau eine Frage. Nur ärgerlich, dass es in dieser Umgebung so viel kostet.
Neo42
Ich habe dies mit Erfolg verwendet, musste aber den letzten Anhang (LINEFEED) in addFilePart () entfernen. Vielen Dank.
David Wood
6

Einfacher, leichter (32k) und viel mehr Leistung:

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

Implementierung:

So senden Sie mit Volley einen POST mit mehreren Teilen / Formulardaten in Android

Hpsaturn
quelle
Die loopj asynchttpclient lib ist fantastisch. Aber es schlägt fehl, wenn Sie mehrere Dateien gleichzeitig hochladen möchten: S
Sebastian Breit
@Perroloco, Sie müssen möglicherweise das Zeitlimit erhöhen, um mit großen / mehreren Dateien erfolgreich zu sein. Die Standardzeitüberschreitung ist möglicherweise zu niedrig. Haben Sie dies mit einer längeren Auszeit versucht? Weil ich es erfolgreich geschafft habe, mehrere Dateien mit loopj gleichzeitig zu senden ...
Chris
Danke @Chris, ich habe es versucht, aber es ist immer noch fehlgeschlagen. Ich habe es geschafft, indem ich mehrere Anfragen ausgeführt habe.
Sebastian Breit
1
loopj haben keine Option, um den Fortschritt anzuzeigen, aber Datei sehr gut hochladen
vuhung3990
danke @Hpsatum Suche vom letzten 6 Stunden Ende, das funktioniert gut !!
Iftikar Urrhman Khan
3

Versuche dies:

    public void SendMultipartFile() {
    Log.d(TAG, "UPLOAD: SendMultipartFile");
    DefaultHttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost( <url> );

    File file = new File("/sdcard/spider.jpg");

    Log.d(TAG, "UPLOAD: setting up multipart entity");

    MultipartEntity mpEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
    Log.d(TAG, "UPLOAD: file length = " + file.length());
    Log.d(TAG, "UPLOAD: file exist = " + file.exists());

    try {
        mpEntity.addPart("datafile", new FileBody(file, "application/octet"));
        mpEntity.addPart("id", new StringBody("1"));
    } catch (UnsupportedEncodingException e1) {
        Log.d(TAG, "UPLOAD: UnsupportedEncodingException");
        e1.printStackTrace();
    }

    httppost.setEntity(mpEntity);
    Log.d(TAG, "UPLOAD: executing request: " + httppost.getRequestLine());
    Log.d(TAG, "UPLOAD: request: " + httppost.getEntity().getContentType().toString());


    HttpResponse response;
    try {
        Log.d(TAG, "UPLOAD: about to execute");
        response = httpclient.execute(httppost);
        Log.d(TAG, "UPLOAD: executed");
        HttpEntity resEntity = response.getEntity();
        Log.d(TAG, "UPLOAD: respose code: " + response.getStatusLine().toString());
        if (resEntity != null) {
            Log.d(TAG, "UPLOAD: " + EntityUtils.toString(resEntity));
        }
        if (resEntity != null) {
            resEntity.consumeContent();
        }
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
Jóni
quelle
1
Dies erfordert eine Drittanbieter-Bibliothek wie im vorherigen Beispiel
Lassi Kinnunen
Verwenden Sie compile 'org.apache.httpcomponents: httpmime: 4.3.4' compile 'org.apache.httpcomponents: httpcore: 4.3.2' für Android Studio-Abhängigkeiten
Tyler Davis
3

Ich kann Loopj nur empfehlen.

Ich habe es erfolgreich verwendet, um mehrere Dateien gleichzeitig hochzuladen, einschließlich verschiedener MIME-Typen. Mach das einfach:

File myVideo = new File("/path/to/myvideo.mp4");
File myPic = new File("/path/to/mypic.jpg");
RequestParams params = new RequestParams();
try {
  params.put("profile_picture", myPic);
  params.put("my_video", myVideo);
} catch(FileNotFoundException e) {}

Bei großen oder vielen Dateien müssen Sie möglicherweise das Zeitlimit erhöhen. Andernfalls wird das Standardzeitlimit verwendet, das möglicherweise zu kurz ist:

client.setTimeout(500000) //make this the appropriate timeout in milliseconds

Unter diesen Links finden Sie eine vollständige Beschreibung von loopj und seiner Verwendung, der mit Abstand einfachsten asynchronen http-Bibliothek, auf die ich gestoßen bin:

http://loopj.com/android-async-http/ http://loopj.com/android-async-http/doc/com/loopj/android/http/AsyncHttpClient.html

Chris
quelle
1

Entfernen Sie alle Ihre httpclient- und httpmime-Abhängigkeiten und fügen Sie diese Abhängigkeit hinzu compile 'commons-httpclient:commons-httpclient:3.1'. Diese Abhängigkeit hat MultipartRequestEntity integriert, sodass Sie problemlos eine oder mehrere Dateien auf den Server hochladen können

public class FileUploadUrlConnection extends AsyncTask<String, String, String> {
private Context context;
private String url;
private List<File> files;

public FileUploadUrlConnection(Context context, String url, List<File> files) {
    this.context = context;
    this.url = url;
    this.files = files;
}

@Override
protected String doInBackground(String... params) {

    HttpClient client = new HttpClient();
    PostMethod post = new PostMethod(url);
    HttpClientParams connectionParams = new HttpClientParams();

    post.setRequestHeader(// Your header goes here );

    try {
        Part[] parts = new Part[files.size()];
        for (int i=0; i<files.size(); i++) {
            Part part = new FilePart(files.get(i).getName(), files.get(i));
            parts[i] = part;
        }

        MultipartRequestEntity entity = new MultipartRequestEntity(parts, connectionParams);

        post.setRequestEntity(entity);

        int statusCode = client.executeMethod(post);
        String response = post.getResponseBodyAsString();

        Log.v("Multipart "," "+response);
        if(statusCode == 200) {
            return response;
        }
    } catch (IOException e) {
        e.printStackTrace();
    } 
 return null;
}

Sie können auch das Anforderungs- und Antwortzeitlimit hinzufügen

client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 10000);
client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 10000);
karthik vishnu kumar
quelle
1
public class Multipart{
    private final Map<String, String> headrs;
    private String url;
    private HttpURLConnection con;
    private OutputStream os;

    private String delimiter = "--";
    private String boundary = "TRR" + Long.toString(System.currentTimeMillis()) + "TRR";

    public Multipart (String url, Map<String, String> headers) {
        this.url = url;
        this.headrs = headers;
    }

    public void connectForMultipart() throws Exception {
        con = (HttpURLConnection) (new URL(url)).openConnection();
        con.setRequestMethod("POST");
        con.setDoInput(true);
        con.setDoOutput(true);
        con.setRequestProperty("Connection", "Keep-Alive");
        for (Map.Entry<String, String> entry : headrs.entrySet()) {
            con.setRequestProperty(entry.getKey(), entry.getValue());
        }
        con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
        con.connect();
        os = con.getOutputStream();
    }

    public void addFormPart(String paramName, String value) throws Exception {
        writeParamData(paramName, value);
    }

    public void addFilePart(String paramName, String fileName, byte[] data) throws Exception {
        os.write((delimiter + boundary + "\r\n").getBytes());
        os.write(("Content-Disposition: form-data; name=\"" + paramName + "\"; filename=\"" + fileName + "\"\r\n").getBytes());
        os.write(("Content-Type: application/octet-stream\r\n").getBytes());
        os.write(("Content-Transfer-Encoding: binary\r\n").getBytes());
        os.write("\r\n".getBytes());

        os.write(data);

        os.write("\r\n".getBytes());
    }

    public void finishMultipart() throws Exception {
        os.write((delimiter + boundary + delimiter + "\r\n").getBytes());
    }


    public String getResponse() throws Exception {
        InputStream is = con.getInputStream();
        byte[] b1 = new byte[1024];
        StringBuffer buffer = new StringBuffer();

        while (is.read(b1) != -1)
            buffer.append(new String(b1));

        con.disconnect();

        return buffer.toString();
    }


    private void writeParamData(String paramName, String value) throws Exception {


        os.write((delimiter + boundary + "\r\n").getBytes());
        os.write("Content-Type: text/plain\r\n".getBytes());//;charset=utf-8
        os.write(("Content-Disposition: form-data; name=\"" + paramName + "\"\r\n").getBytes());
        ;
        os.write(("\r\n" + value + "\r\n").getBytes());


    }
}

Dann rufen Sie unten an

Multipart multipart = new Multipart(url__, map);
            multipart .connectForMultipart();
multipart .addFormPart(entry.getKey(), entry.getValue());
multipart .addFilePart(KeyName, "FileName", imagedata);
multipart .finishMultipart();
VV W.
quelle
0

Ich kann Ion Library empfehlen, es verwendet 3 Abhängigkeiten und Sie können alle drei JAR-Dateien auf diesen beiden Sites finden:
https://github.com/koush/ion#jars (ion und androidasync)

https://code.google.com/p/google-gson/downloads/list (gson)

try {
   Ion.with(this, "http://www.urlthatyouwant.com/post/page")
   .setMultipartParameter("field1", "This is field number 1")
   .setMultipartParameter("field2", "Field 2 is shorter")
   .setMultipartFile("imagefile",
        new File(Environment.getExternalStorageDirectory()+"/testfile.jpg"))
   .asString()
   .setCallback(new FutureCallback<String>() {
        @Override
        public void onCompleted(Exception e, String result) {
             System.out.println(result);
        }});
   } catch(Exception e) {
     // Do something about exceptions
        System.out.println("exception: " + e);
   }

Dies wird asynchron ausgeführt und der Rückruf wird im UI-Thread ausgeführt, sobald eine Antwort eingeht. Ich empfehle dringend, dass Sie unter https://github.com/koush/ion weitere Informationen finden

Alejandro Serret
quelle
0

Hier ist ein einfacher Ansatz, wenn Sie die AOSP-Bibliothek verwenden Volley .

Erweitern Sie die Klasse Request<T>wie folgt:

public class MultipartRequest extends Request<String> {
    private static final String FILE_PART_NAME = "file";
    private final Response.Listener<String> mListener;
    private final Map<String, File> mFilePart;
    private final Map<String, String> mStringPart;
    MultipartEntityBuilder entity = MultipartEntityBuilder.create();
    HttpEntity httpentity;

    public MultipartRequest(String url, Response.ErrorListener errorListener,
                            Response.Listener<String> listener, Map<String, File> file,
                            Map<String, String> mStringPart) {
        super(Method.POST, url, errorListener);
        mListener = listener;
        mFilePart = file;
        this.mStringPart = mStringPart;
        entity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        buildMultipartEntity();
    }

    public void addStringBody(String param, String value) {
        mStringPart.put(param, value);
    }

    private void buildMultipartEntity() {
        for (Map.Entry<String, File> entry : mFilePart.entrySet()) {
            // entity.addPart(entry.getKey(), new FileBody(entry.getValue(), ContentType.create("image/jpeg"), entry.getKey()));
            try {
                entity.addBinaryBody(entry.getKey(), Utils.toByteArray(new FileInputStream(entry.getValue())), ContentType.create("image/jpeg"), entry.getKey() + ".JPG");
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
        for (Map.Entry<String, String> entry : mStringPart.entrySet()) {
            if (entry.getKey() != null && entry.getValue() != null) {
                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 = entity.build();
            httpentity.writeTo(bos);
        } catch (IOException e) {
            VolleyLog.e("IOException writing to ByteArrayOutputStream");
        }
        return bos.toByteArray();
    }

    @Override
    protected Response<String> parseNetworkResponse(NetworkResponse response) {
        Log.d("Response", new String(response.data));
        return Response.success(new String(response.data), getCacheEntry());
    }

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

Sie können eine Anfrage erstellen und hinzufügen, z.

Map<String, String> params = new HashMap<>();
        params.put("name", name.getText().toString());
        params.put("email", email.getText().toString());
        params.put("user_id", appPreferences.getInt( Utils.PROPERTY_USER_ID, -1) + "");
        params.put("password", password.getText().toString());
        params.put("imageName", pictureName);
        Map<String, File> files = new HashMap<>();
        files.put("photo", new File(Utils.LOCAL_RESOURCE_PATH + pictureName));
        MultipartRequest multipartRequest = new MultipartRequest(Utils.BASE_URL + "editprofile/" + appPreferences.getInt(Utils.PROPERTY_USER_ID, -1), new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                // TODO Auto-generated method stub
                Log.d("Error: ", error.toString());
                FugaDialog.showErrorDialog(ProfileActivity.this);
            }
        }, new Response.Listener<String>() {
            @Override
            public void onResponse(String jsonResponse) {
                JSONObject response = null;
                try {
                    Log.d("jsonResponse: ", jsonResponse);
                    response = new JSONObject(jsonResponse);

                } catch (JSONException e) {
                    e.printStackTrace();
                }
                try {
                    if (response != null && response.has("statusmessage") && response.getBoolean("statusmessage")) {
                        updateLocalRecord();

                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                FugaDialog.dismiss();
            }

        }, files, params);
        RequestQueue queue = Volley.newRequestQueue(this);
        queue.add(multipartRequest);
Sanjeet A.
quelle
0

Für die Nachwelt habe ich okhttp nicht erwähnt. Verwandter Beitrag.

Grundsätzlich bauen Sie den Körper mit einem MultipartBody.Builder auf und veröffentlichen ihn dann in einer Anfrage.

Beispiel in Kotlin:

    val body = MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart(
                "file", 
                file.getName(),
                RequestBody.create(MediaType.parse("image/png"), file)
            )
            .addFormDataPart("timestamp", Date().time.toString())
            .build()

    val request = Request.Builder()
            .url(url)
            .post(body)
            .build()

    httpClient.newCall(request).enqueue(object : okhttp3.Callback {
        override fun onFailure(call: Call?, e: IOException?) {
            ...
        }

        override fun onResponse(call: Call?, response: Response?) {
            ...
        }
    })
RecencyEffect
quelle
0

Sie können GentleRequest verwenden, eine leichtgewichtige Bibliothek zum Erstellen von http-Anfragen (HAFTUNGSAUSSCHLUSS: Ich bin der Autor):

Connections connections = new HttpConnections();
Binary binary = new PacketsBinary(new 
BufferedInputStream(new FileInputStream(file)), 
   file.length());
//Content-Type is set to multipart/form-data; boundary= 
//{generated by multipart object}
MultipartForm multipart = new HttpMultipartForm(
    new HttpFormPart("user", "aplication/json", 
       new JSONObject().toString().getBytes()),
    new HttpFormPart("java", "java.png", "image/png", 
       binary.content()));
Response response = connections.response(new 
    PostRequest(url, multipart));
if (response.hasSuccessCode()) {
    byte[] raw = response.body().value();
    String string = response.body().stringValue();
    JSONOBject json = response.body().jsonValue();
 } else {

 }

Probieren Sie es aus: https://github.com/Iprogrammerr/Gentle-Request

Igor
quelle