Preciso fazer upload Arraylist
de imagens para o servidor sem usar nenhuma biblioteca. Estou usando o Asynctask
upload de uma única imagem e ela está funcionando perfeitamente com a ajuda do httpurlconnection multipart / form-data. Agora eu preciso alterar meu código para fazer upload de vários arquivos de qualquer tipo usando, Arraylist<String>
mas meu problema é que o código existente FileinputStream
não suporta arraylist e não tenho idéia do que usar em vez de Fileinputstream
fazer upload de arraylist para o servidor e não quer usar qualquer biblioteca para isso também.
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;
}
}
Eu também tentei colocar FileInputStream
em loop, mas o upload de imagens em vários pedidos não é o que eu quero. Meu servidor exige que o aplicativo faça uma solicitação única para n número de imagens. Qualquer ajuda seria apreciada, mas sem o uso de qualquer biblioteca
Respostas:
OBSERVAÇÃO: não tentei se esse código funciona corretamente com a HttpURLConnection, mas deveria.
Pelo que li da internet, você ainda pode usar o loop mencionado, mas com algumas modificações.
Segui o tutorial sobre multipart / form-data aqui dev.to , para tornar isso mais um post de aprendizado, vou lhe dizer qual é esse método que deve acontecer.
Os dados multipart / form são enviados assim
O que eu faria é criar um novo método, mas você pode simplesmente escrever o código no seu método já existente.
Você deseja escrever é o limite seguido pela disposição e depois pelos dados . Faça isso para todos os arquivos e envie o limite de fechamento . Isso irá gerar a estrutura multipart / dados de formulário que você deseja.
No código psudo isso seria
O código pode ser escrito assim, primeiro você define suas variáveis
Aqui é onde os dados serão gerados. Começa com a concatenação do limite e a leitura dos dados. Esses dados são gravados no fluxo e você continua o loop para todos os arquivos / imagens.
Agora, a matriz de bytes
sendData
conterá os dados de várias partes / formulário que você precisa enviar com sua HttpURLConnection.Eu não sou tão ativo aqui há muito tempo. Diga-me se você precisa de mais algumas especificações ou que esclareço meu texto: D
fonte
FileinputStream não suporta o ArrayList. Mas há uma maneira de contornar usando ObjectOutputStream . Também serializará seu ArrayList. Verifique as alterações no código.
Happy Coding :)
fonte
Não tenho certeza se o uso de tarefa assíncrona única é uma obrigação para você.
Como você disse, seu código funciona absolutamente bem para uma única imagem. Portanto, para carregar vários arquivos da arraylist, basta modificar um pouco o seu AsyncTask. Basta fazer upload de um arquivo após o outro. Ou se você não quiser fazer tanta modificação, simplesmente declare a variável global que mantém o índice do item que está sendo carregado e, no OnPostExecute, crie uma nova instância da tarefa assíncrona e passe o próximo item no arraylist. Espero que isso esteja claro.
fonte