Necesito subir Arraylist
imágenes al servidor sin usar ninguna biblioteca. Estoy usando Asynctask
para cargar una sola imagen y funciona perfectamente con la ayuda de httpurlconnection multipart / form-data. Ahora necesito cambiar mi código para cargar múltiples archivos de cualquier tipo usando, Arraylist<String>
pero mi problema es que el código existente FileinputStream
no admite la lista de arrays y no tengo idea de qué usar en lugar de Fileinputstream
cargar la lista de arrays en el servidor y no quiero usar cualquier biblioteca para esto tampoco.
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;
}
}
También intenté ponerlo FileInputStream
en bucle, pero cargar imágenes en solicitudes múltiples no es lo que quiero. La aplicación de mi servidor requiere que realice una solicitud única para n número de imágenes. Cualquier ayuda sería apreciada pero sin el uso de ninguna biblioteca.
Respuestas:
Tenga en cuenta que no lo he intentado si este código realmente funciona con HttpURLConnection, pero debería.
Por lo que he leído en Internet, aún puedes usar el ciclo que mencionaste pero con algunas modificaciones.
Seguí el tutorial sobre multipart / form-data aquí dev.to , para que esto sea más una publicación de aprendizaje, te diré qué es este método y qué debería suceder.
Los datos multiparte / formulario se envían así
Lo que haría es crear un nuevo método, pero puede escribir el código en su método ya existente.
Desea escribir es el límite seguido de la disposición y luego los datos . Haga eso para todos los archivos y luego envíe el límite de cierre . Esto generará los datos multiparte / formulario estructura que desee.
En psudocódigo esto sería
El código podría escribirse así, primero debes definir tus variables
Aquí es donde se generarán los datos. Comienza con la concatenación del límite y luego la lectura de los datos. Esos datos se escriben en la secuencia y continúa el ciclo para todos los archivos / imágenes.
Ahora, la matriz de bytes
sendData
contendrá los datos multiparte / formulario que debe enviar con su HttpURLConnection.No he estado tan activo aquí por mucho tiempo. Dime si necesitas más especificaciones o si aclaro mi texto: D
fuente
FileinputStream no es compatible con ArrayList. Pero hay una forma de evitarlo usando ObjectOutputStream . También serializará su ArrayList. Verifique los cambios en el código.
Happy Coding :)
fuente
No estoy seguro si usar una sola tarea asíncrona es imprescindible para usted
Como dijiste, tu código funciona absolutamente bien para una sola imagen. Entonces, para cargar varios archivos desde la lista de arrays, simplemente necesita modificar un poco su AsyncTask. Simplemente cargue un archivo después de otro O si incluso no desea hacer tanta modificación, simplemente declare la variable global que contiene el índice del elemento que se está cargando y en OnPostExecute cree una nueva instancia de la tarea asíncrona y pase el siguiente elemento en la lista de arrays. Espero que esto esté claro.
fuente