Ponieważ programiści Androida zalecają używanie tej HttpURLConnection
klasy, zastanawiałem się, czy ktoś może podać mi dobry przykład, jak wysłać „plik” mapy bitowej (właściwie strumień w pamięci) przez POST do serwera HTTP Apache. Nie interesują mnie pliki cookie, uwierzytelnianie ani nic skomplikowanego, ale chcę mieć niezawodną i logiczną implementację. Wszystkie przykłady, które tu widziałem, wyglądają bardziej jak „spróbujmy tego i może zadziała”.
W tej chwili mam ten kod:
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL("http://example.com/server.cgi");
urlConnection = (HttpURLConnection) url.openConnection();
} catch (Exception e) {
this.showDialog(getApplicationContext(), e.getMessage());
}
finally {
if (urlConnection != null)
{
urlConnection.disconnect();
}
}
gdzie showDialog powinien po prostu wyświetlać AlertDialog
(w przypadku nieprawidłowego adresu URL?).
Teraz powiedzmy, że generuję mapę bitową w ten sposób: Bitmap image = this.getBitmap()
wewnątrz kontrolki pochodzącej z View
i chcę ją wysłać przez POST. Jaka byłaby właściwa procedura, aby to osiągnąć? Z jakich klas muszę korzystać? Czy mogę użyć HttpPost
jak w tym przykładzie ? Jeśli tak, jak powinienem skonstruować plikInputStreamEntity
dla mojej mapy bitowej? Byłoby odrażające, gdyby trzeba było najpierw zapisać bitmapę w pliku na urządzeniu.
Powinienem też wspomnieć, że naprawdę muszę wysłać każdy niezmieniony piksel oryginalnej mapy bitowej na serwer, więc nie mogę go przekonwertować na JPEG.
źródło
Odpowiedzi:
Nie mam pojęcia, dlaczego
HttpURLConnection
klasa nie zapewnia żadnych środków do wysyłania plików bez konieczności ręcznego tworzenia opakowania pliku. Oto, co ostatecznie zrobiłem, ale jeśli ktoś zna lepsze rozwiązanie, daj mi znać.Dane wejściowe:
Rzeczy statyczne:
Skonfiguruj żądanie:
Rozpocznij opakowanie treści:
Konwertuj
Bitmap
naByteBuffer
:Opakowanie zawartości końcowej:
Opróżnij bufor wyjściowy:
Otrzymać odpowiedź:
Zamknij strumień odpowiedzi:
Zamknij połączenie:
PS: Oczywiście musiałem zawrzeć żądanie
private class AsyncUploadBitmaps extends AsyncTask<Bitmap, Void, String>
, aby platforma Android była zadowolona, ponieważ nie lubi mieć żądań sieciowych w głównym wątku.źródło
url
zmiennej, tak jak poniżej:URL url = new URL("http://example.com/?param1=val1¶m2=val2");
. Możesz dodać tyle, ile chcesz (chociaż myślę, że są pewne ograniczenia).Właściwie znalazłem lepszy sposób wysyłania plików za pomocą HttpURLConnection przy użyciu MultipartEntity
Zakładając, że przesyłasz obraz z danymi bitmapy:
I Voila! Twoje dane postu będą zawierały pole obrazu wraz z nazwą pliku i ścieżką na serwerze.
źródło
Aby
MultipartUtility
w prosty sposób przesłać plik na serwer z jakimś parametrem .MultipartUtility.java
Do
upload
Ciebiefile
wraz z parametrami.UWAGA: umieść ten kod poniżej w wątku innym niż ui, aby uzyskać odpowiedź.
źródło
Rozwiązanie Jaydipsinh Zala nie zadziałało dla mnie, nie wiem dlaczego, ale wydaje się być blisko rozwiązania.
Łącząc to ze świetnym rozwiązaniem i wyjaśnieniem Mihaia Todora , otrzymaliśmy tę klasę, która obecnie działa dla mnie. Jeśli to komuś pomoże:
MultipartUtility2V.java
źródło
Ta odpowiedź https://stackoverflow.com/a/33149413/6481542 zapewniła mi 90% możliwości przesyłania dużych plików na programistyczny serwer Django, ale musiałem użyć setFixedLengthStreamingMode, aby to zadziałało. Wymaga to ustawienia Content-Length przed napisaniem treści, co wymaga dość znaczącego przepisania powyższej odpowiedzi. Oto mój wynik końcowy
Użycie jest w dużej mierze takie samo jak w powyższej odpowiedzi, ale dołączyłem obsługę CSRF, której Django używa domyślnie z formularzami
źródło
bazując na rozwiązaniu Mihai, jeśli ktoś ma problem z zapisaniem obrazów na serwerze jak to, co się stało na moim serwerze. zmień część Bitmap to bytebuffer na:
źródło
Nie testowałem tego, ale możesz spróbować użyć PipedInputStream i PipedOutputStream. Może to wyglądać następująco:
źródło
Oto, co zrobiłem, aby przesłać zdjęcie za pomocą prośby o wpis.
UWAGA: Ten kod wymaga bibliotek, więc postępuj zgodnie z instrukcjami tutaj , aby pobrać biblioteki.
źródło
HttpClient
(Twój link jest nieaktualny. Zamiast tego użyj tej ), którą chłopaki z Androidem zachowują tylko ze względu na kompatybilność wsteczną, zamiast używać wbudowanejHttpURLConnection
. Z drugiej strony wygląda na to, że konfiguracja wymaga więcej pracy, więc może nie jest to warte wysiłku.Używanie okHttp było o wiele łatwiejsze, ponieważ nie mogłem uruchomić żadnego z tych rozwiązań: https://stackoverflow.com/a/37942387/447549
źródło
Wypróbowałem powyższe rozwiązania i żadne nie działało dla mnie po wyjęciu z pudełka.
Jednak http://www.baeldung.com/httpclient-post-http-request . Linia 6 POST Multipart Request działała w ciągu kilku sekund
źródło