Posso estar errado nisso, mas acho que você precisa implementar o seu próprio com.android.volley.toolbox.HttpStack
para isso porque os padrões ( HurlStack
se a versão> Gingerbread ou HttpClientStack
) não lidam com multipart/form-data
.
Editar:
E de fato eu estava errado. Consegui fazer isso usando MultipartEntity
em Request assim:
public class MultipartRequest extends Request<String> {
private MultipartEntity entity = new MultipartEntity();
private static final String FILE_PART_NAME = "file";
private static final String STRING_PART_NAME = "text";
private final Response.Listener<String> mListener;
private final File mFilePart;
private final String mStringPart;
public MultipartRequest(String url, Response.ErrorListener errorListener, Response.Listener<String> listener, File file, String stringPart)
{
super(Method.POST, url, errorListener);
mListener = listener;
mFilePart = file;
mStringPart = stringPart;
buildMultipartEntity();
}
private void buildMultipartEntity()
{
entity.addPart(FILE_PART_NAME, new FileBody(mFilePart));
try
{
entity.addPart(STRING_PART_NAME, new StringBody(mStringPart));
}
catch (UnsupportedEncodingException e)
{
VolleyLog.e("UnsupportedEncodingException");
}
}
@Override
public String getBodyContentType()
{
return entity.getContentType().getValue();
}
@Override
public byte[] getBody() throws AuthFailureError
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try
{
entity.writeTo(bos);
}
catch (IOException e)
{
VolleyLog.e("IOException writing to ByteArrayOutputStream");
}
return bos.toByteArray();
}
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response)
{
return Response.success("Uploaded", getCacheEntry());
}
@Override
protected void deliverResponse(String response)
{
mListener.onResponse(response);
}
}
É bem cru, mas tentei com uma imagem e um barbante simples e funcionou. A resposta é um espaço reservado, não faz muito sentido retornar uma string de resposta neste caso. Tive problemas ao usar o apache httpmime para usar o MultipartEntity, então usei este https://code.google.com/p/httpclientandroidlib/ não sei se existe uma maneira melhor. Espero que ajude.
Editar
Você pode usar httpmime sem usar httpclientandroidlib, a única dependência é httpcore.
Conforme mencionado na apresentação no I / O (cerca de 4:05), o Volley "é terrível" para cargas úteis grandes. Pelo que entendi, isso significa não usar o Volley para receber / enviar arquivos (grandes). Olhando para o código, parece que ele nem mesmo foi projetado para lidar com dados de formulário com várias partes (por exemplo, Request.java tem getBodyContentType () com "application / x-www-form-urlencoded" codificado; HttpClientStack :: createHttpRequest () pode lidar apenas com byte [], etc ...). Provavelmente, você será capaz de criar uma implementação que pode lidar com multipartes, mas se eu fosse você usaria HttpClient diretamente com MultipartEntity como:
Você pode precisar do HttpClient mais recente (ou seja, não o integrado) ou, melhor ainda, use o Volley com o HttpClient mais recente
fonte
ATUALIZAÇÃO 26/08/2015:
Se você não quiser usar HttpEntity obsoleto, aqui está meu código de amostra de trabalho (testado com ASP.Net WebAPI)
MultipartActivity.java
BaseVolleyRequest.java:
FIM DA ATUALIZAÇÃO
Este é meu código de amostra de trabalho (testado apenas com arquivos de tamanho pequeno):
fonte
Uso de amostra
fonte
Uma abordagem muito simples para o desenvolvedor que deseja apenas enviar parâmetros POST em uma solicitação multiparte.
Primeiro defina essas constantes:
Adicione uma função auxiliar para criar um corpo de postagem para você:
Substitua getBody () e getBodyContentType
fonte
sbPost.append("--" + BOUNDARY + "--");
isso antes de retornar, pois a API que estou usando exige uma tag de fechamentoPrimeira resposta em SO.
Eu encontrei o mesmo problema e achei o código do @alex muito útil. Fiz algumas modificações simples para passar quantos parâmetros forem necessários por meio do HashMap e basicamente copiei
parseNetworkResponse()
de StringRequest. Eu pesquisei online e fiquei muito surpreso ao descobrir que uma tarefa tão comum raramente é respondida. De qualquer forma, gostaria que o código pudesse ajudar:E você pode usar a classe da seguinte forma:
fonte
Outra solução, muito leve com alto desempenho com grande carga útil:
Biblioteca cliente Http Android Assíncrona: http://loopj.com/android-async-http/
fonte
Aqui está uma solução simples e um exemplo completo para enviar arquivos usando o Volley Android
1) Importação do Gradle
2) Agora crie uma classe RequestManager
3) Agora crie uma classe para lidar com a solicitação de upload de arquivo WebService
4) E agora chame o método como este para acessar o serviço
fonte
Esta é a minha maneira de fazer isso. Pode ser útil para outras pessoas:
fonte