Muszę przesłać Arraylist
obrazy na serwer bez korzystania z biblioteki. Używam Asynctask
do przesyłania pojedynczego obrazu i działa idealnie przy pomocy httpurlconnection multipart / form-data. Teraz muszę zmienić kod, aby przesyłać wiele plików dowolnego typu za pomocą, Arraylist<String>
ale moim problemem jest to, że istniejący kod FileinputStream
nie obsługuje listy arraylist i nie mam pojęcia, czego użyć zamiast Fileinputstream
przesyłać listę arraylist na serwer, a ja nie chcę użyć do tego dowolnej biblioteki.
public class multipart_test extends AsyncTask<Void,Void,String> {
Context context;
String Images;
public static final String TAG = "###Image Uploading###";
public multipart_test(Context context,String Upload_Images) {
this.context = context;
this.Images = Upload_Images;
}
@Override
protected String doInBackground(Void... params) {
BufferedReader reader;
String WebPath = null;
try {
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1024 * 1024;
//todo change URL as per client ( MOST IMPORTANT )
URL url = new URL("10.0.0.1/uploadMultipart.php");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// Allow Inputs & Outputs.
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
// Set HTTP method to POST.
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
FileInputStream fileInputStream;
DataOutputStream outputStream;
outputStream = new DataOutputStream(connection.getOutputStream());
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream.writeBytes("Content-Disposition: form-data; name=\"reference\""+ lineEnd);
outputStream.writeBytes(lineEnd);
//outputStream.writeBytes("my_refrence_text");
outputStream.writeBytes(lineEnd);
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream.writeBytes("Content-Disposition: form-data; name=\"uploadFile\";filename=\"" + "profileImage" +"\"" + lineEnd);
outputStream.writeBytes(lineEnd);
//Dummy ArrayList for upload
ArrayList<String> uploadFiles = new ArrayList<>();
uploadFiles.add(Images);
uploadFiles.add(Images);
uploadFiles.add(Images);
uploadFiles.add(Images);
fileInputStream = new FileInputStream(uploadFiles); // NOT SUPPORTING ARRAYLIST HERE
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// Read file
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
outputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
outputStream.writeBytes(lineEnd);
outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
fileInputStream.close();
}
// Responses from the server (code and message)
int serverResponseCode = connection.getResponseCode();
String result = null;
if (serverResponseCode == 200) {
StringBuilder s_buffer = new StringBuilder();
InputStream is = new BufferedInputStream(connection.getInputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String inputLine;
while ((inputLine = br.readLine()) != null) {
s_buffer.append(inputLine);
}
result = s_buffer.toString();
}
connection.getInputStream().close();
outputStream.flush();
outputStream.close();
if (result != null) {
Log.d("result_for upload", result);
}
return WebPath;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
Próbowałem także FileInputStream
zapętlić, ale przesyłanie obrazów do wielu żądań nie jest tym, czego chcę. Aplikacja mojego serwera wymaga pojedynczego żądania n liczby obrazów. Każda pomoc byłaby mile widziana, ale bez użycia biblioteki
Odpowiedzi:
UWAGA: nie próbowałem, czy ten kod faktycznie działa z HttpURLConnection, ale powinien.
Z tego, co przeczytałem w Internecie, nadal możesz używać wspomnianej pętli, ale z pewnymi modyfikacjami.
Wykonałem samouczek dotyczący danych wieloczęściowych / formularzy tutaj dev.to , aby uczynić to bardziej postem edukacyjnym, powiem ci, co to za metoda, co powinno się stać.
Dane wieloczęściowe / formularze są wysyłane w ten sposób
Chciałbym stworzyć nową metodę, ale możesz po prostu napisać kod w swojej już istniejącej metodzie.
Chcesz napisać to granica, po której następuje dyspozycja, a następnie dane . Zrób to dla wszystkich plików, a następnie wyślij granicę zamknięcia . Spowoduje to wygenerowanie pożądanej struktury danych wieloczęściowych / formularzy .
W psudo-code byłoby to
Kod można zapisać w ten sposób, najpierw zdefiniujesz zmienne
Oto, gdzie zostaną wygenerowane dane. Zaczyna się od konkatenacji granicy, a następnie odczytania danych. Te dane są zapisywane w strumieniu i kontynuujesz pętlę dla wszystkich plików / obrazów.
Teraz tablica bajtów
sendData
będzie zawierać dane wieloczęściowe / formularze , które należy wysłać za pomocą HttpURLConnection.Dawno nie byłem tu tak aktywny. Powiedz mi, czy potrzebujesz więcej specyfikacji lub wyjaśnię swój tekst: D
źródło
FileinputStream nie obsługuje ArrayList. Ale można to obejść za pomocą ObjectOutputStream . Będzie również serializować twoją ArrayList. Sprawdź zmiany w kodzie.
Happy Coding :)
źródło
Nie jestem pewien, czy korzystanie z pojedynczego zadania asynchronicznego jest dla Ciebie koniecznością.
Jak powiedziałeś, twój kod działa absolutnie dobrze dla pojedynczego obrazu. Aby przesłać wiele plików z listy arraylist, wystarczy trochę zmodyfikować AsyncTask. Po prostu prześlij jeden plik po drugim Lub jeśli nawet nie chcesz dokonywać tak wielu modyfikacji, po prostu zadeklaruj zmienną globalną zawierającą indeks przesyłanego elementu, a OnPostExecute utwórz nową instancję zadania asynchronicznego i przekaż następny element na liście arraylist. Mam nadzieję, że to jasne.
źródło