2010-05-29 8 views
116

Ich möchte ein Bild von der Android-Client an den Django-Server mit Http Post senden. Das Bild wird aus der Galerie ausgewählt. Momentan verwende ich Listenwertname Pairs, um die notwendigen Daten an den Server zu senden und Antworten von Django in JSON zu empfangen. Kann derselbe Ansatz für Bilder verwendet werden (mit URLs für Bilder, die in JSON-Antworten eingebettet sind)?Senden von Bildern mit Http Post

Auch, was ist eine bessere Methode: Bilder aus der Ferne zugreifen, ohne sie vom Server herunterladen oder herunterladen und in einem Bitmap-Array speichern und lokal verwenden? Die Bilder sind wenige (< 10) und klein (50 * 50 Dip).

Jedes Tutorial, um diese Probleme anzugehen, würde sehr geschätzt werden.

Bearbeiten: Die aus der Galerie ausgewählten Bilder werden nach Skalierung auf die erforderliche Größe an den Server gesendet.

Antwort

140

Ich gehe davon aus, dass Sie den Pfad und den Dateinamen des Bildes kennen, die Sie hochladen möchten. Fügen Sie diese Zeichenfolge zu Ihrem NameValuePair hinzu, indem Sie image als Schlüsselname verwenden.

Das Senden von Bildern kann mit der HttpComponents libraries erfolgen. Laden Sie die aktuelle Httpclient (derzeit 4.0.1) binär mit Abhängigkeiten Paket und kopieren apache-mime4j-0.6.jar und httpmime-4.0.1.jar zu Ihrem Projekt und fügen Sie sie in Ihrem Java-Build-Pfad.

Sie müssen die folgenden Importe zu Ihrer Klasse hinzufügen.

import org.apache.http.entity.mime.HttpMultipartMode; 
import org.apache.http.entity.mime.MultipartEntity; 
import org.apache.http.entity.mime.content.FileBody; 
import org.apache.http.entity.mime.content.StringBody; 

Jetzt können Sie einen MultipartEntity erstellen ein Bild zu Ihrer POST-Anforderung zu befestigen. Der folgende Code zeigt ein Beispiel dafür:

public void post(String url, List<NameValuePair> nameValuePairs) { 
    HttpClient httpClient = new DefaultHttpClient(); 
    HttpContext localContext = new BasicHttpContext(); 
    HttpPost httpPost = new HttpPost(url); 

    try { 
     MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE); 

     for(int index=0; index < nameValuePairs.size(); index++) { 
      if(nameValuePairs.get(index).getName().equalsIgnoreCase("image")) { 
       // If the key equals to "image", we use FileBody to transfer the data 
       entity.addPart(nameValuePairs.get(index).getName(), new FileBody(new File (nameValuePairs.get(index).getValue()))); 
      } else { 
       // Normal string data 
       entity.addPart(nameValuePairs.get(index).getName(), new StringBody(nameValuePairs.get(index).getValue())); 
      } 
     } 

     httpPost.setEntity(entity); 

     HttpResponse response = httpClient.execute(httpPost, localContext); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

Ich hoffe, das hilft Ihnen ein bisschen in die richtige Richtung.

+0

Wie ich bereits erwähnt habe, sind die Bilder, die ich sende, klein. Also muss ich MultiPartEntity verwenden, um sie zu senden? – primpap

+6

Ich würde das definitiv empfehlen. Auf diese Weise können Sie wahrscheinlich Django-Funktionen verwenden, um das Bild zu erhalten und es einfach zu speichern. Ein anderer Weg wäre, den Byte-Stream vom Image in eine Base64-codierte Zeichenfolge zu codieren und die Server-Seite zu dekodieren. Aber das wäre meiner Meinung nach zu mühsam und nicht der richtige Weg. – Piro

+0

Die aus der Galerie ausgewählten Bilder werden nach Skalierung auf 50 * 50 Dip an den Server gesendet. Daher habe ich keinen Pfad, der zu Paaren von Wertnamen hinzugefügt werden kann. Also scheint nur der zweite Ansatz möglich zu sein. – primpap

-12

Ich tue dies in der Regel in dem Thread die Json Antwort Handhabung:

try { 
    Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(imageUrl).getContent()); 
} catch (MalformedURLException e) { 
    e.printStackTrace(); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 

Wenn Sie Transformationen auf das Bild tun müssen, wollen Sie eine Drawable statt einer Bitmap erstellen.

+3

Die Frage ist, wie man ein Bild zu schreiben, und nicht, wie es zu bekommen. – dwbrito

13

Version 4.3.5 aktualisiert-Code

  • Httpclient-4.3.5.jar
  • httpcore-4.3.2.jar
  • httpmime-4.3.5.jar

Seit MultipartEntity hat veraltet. Bitte beachten Sie den folgenden Code.

String responseBody = "failure"; 
HttpClient client = new DefaultHttpClient(); 
client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1); 

String url = WWPApi.URL_USERS; 
Map<String, String> map = new HashMap<String, String>(); 
map.put("user_id", String.valueOf(userId)); 
map.put("action", "update"); 
url = addQueryParams(map, url); 

HttpPost post = new HttpPost(url); 
post.addHeader("Accept", "application/json"); 

MultipartEntityBuilder builder = MultipartEntityBuilder.create(); 
builder.setCharset(MIME.UTF8_CHARSET); 

if (career != null) 
    builder.addTextBody("career", career, ContentType.create("text/plain", MIME.UTF8_CHARSET)); 
if (gender != null) 
    builder.addTextBody("gender", gender, ContentType.create("text/plain", MIME.UTF8_CHARSET)); 
if (username != null) 
    builder.addTextBody("username", username, ContentType.create("text/plain", MIME.UTF8_CHARSET)); 
if (email != null) 
    builder.addTextBody("email", email, ContentType.create("text/plain", MIME.UTF8_CHARSET)); 
if (password != null) 
    builder.addTextBody("password", password, ContentType.create("text/plain", MIME.UTF8_CHARSET)); 
if (country != null) 
    builder.addTextBody("country", country, ContentType.create("text/plain", MIME.UTF8_CHARSET)); 
if (file != null) 
    builder.addBinaryBody("Filedata", file, ContentType.MULTIPART_FORM_DATA, file.getName()); 

post.setEntity(builder.build()); 

try { 
    responseBody = EntityUtils.toString(client.execute(post).getEntity(), "UTF-8"); 
// System.out.println("Response from Server ==> " + responseBody); 

    JSONObject object = new JSONObject(responseBody); 
    Boolean success = object.optBoolean("success"); 
    String message = object.optString("error"); 

    if (!success) { 
     responseBody = message; 
    } else { 
     responseBody = "success"; 
    } 

} catch (Exception e) { 
    e.printStackTrace(); 
} finally { 
    client.getConnectionManager().shutdown(); 
} 
+0

Welche JAR-Pakete werden benötigt? –

+3

httpclient-4.3.5.jar httpcore-4.3.2.jar httpmime-4.3.5.jar –

+0

Was gibt addQueryParams zurück? – San

9

Die loopj Bibliothek kann straight-forward für diesen Zweck verwendet werden:

SyncHttpClient client = new SyncHttpClient(); 
RequestParams params = new RequestParams(); 
params.put("text", "some string"); 
params.put("image", new File(imagePath)); 

client.post("http://example.com", params, new TextHttpResponseHandler() { 
    @Override 
    public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) { 
    // error handling 
    } 

    @Override 
    public void onSuccess(int statusCode, Header[] headers, String responseString) { 
    // success 
    } 
}); 

http://loopj.com/

+0

Danke !!! rettete mir Zeit .... –

5

ich viel zu kämpfen versucht, ein Bild zu implementieren von Android-Client Posting auf Servlet httpclient-4.3.5.jar, httpcore-4.3.2.jar, httpmime-4.3.5.jar. Ich habe immer einen Laufzeitfehler bekommen. Ich habe herausgefunden, dass Sie diese Gläser im Grunde nicht mit Android verwenden können, da Google eine ältere Version von HttpClient in Android verwendet. Die Erklärung ist hier http://hc.apache.org/httpcomponents-client-4.3.x/android-port.html. Sie müssen das httpclientandroidlib-1.2.1-Jar von android http-client library abrufen. Ändern Sie dann Ihre Importe von or.apache.http.client in ch.boye.httpclientandroidlib. Hoffe das hilft.