[RESOLVIDO] Setar timeout ao enviar dados via post (Android)

Olá Pessoal!

Estou desenvolvendo um projeto para Android que envia dados via POST para um servidor.
A minha aplicação já está detectando:

  • quando o Wifi do celular não está ligado;
  • quando o Wifi está ligado, mas não está conectado.
  • quando o Wifi está ligado e conectado a uma rede.

O problema da minha aplicação é quando a qualidade do sinal wireless está num nível muito baixo, e a minha aplicação envia dados via post e fica esperando mais de um minuto pela resposta, até cair numa exceção:

Ou seja, está caindo em timeout.

Eu quero configurar o timeout pra 1 segundo (mais ou menos) pra minha aplicação não ficar travada, e dar uma resposta logo.
Eu tentei fazer isso pra resolver:

[code]
List<NameValuePair> dados = new ArrayList<NameValuePair>();
dados.add(new BasicNameValuePair("pesquisa", "teste");

HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://127.0.0.1/teste.php");
httppost.setEntity(new UrlEncodedFormEntity(dados));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();

HttpConnectionParams.setConnectionTimeout(httppost.getParams(), 100); //eu tentei setar o timeout aqui

int i;
StringBuilder stringBuilder = new StringBuilder();

while ((i = is.read()) >= 0) {
stringBuilder.append((char) i);
}

System.out.println(stringBuilder.toString());[/code]

Como que eu posso setar o timeout aqui?

Obrigada

Oi,

Não sei se é melhor mas para comunicação http, para enviar dados e receber resposta, existe a classe URLConnection. :wink:

abs,

Evandro

Oi Eliangela!

Então, na hora que você seta o timeout o httpclient já executou o post. Tente colocar a linha do timeout antes de chamar o execute.

Outra coisa, você está fazendo essa requisição em outra thread?

[quote=Evandro_Contato]Oi,

Não sei se é melhor mas para comunicação http, para enviar dados e receber resposta, existe a classe URLConnection. :wink:

abs,

Evandro[/quote]

Oi Evandro!
Eu preciso usar post mesmo. Existe uma maneira de setar o timeout, mas eu devo estar fazendo errado.

[ ]'s

[quote=toshikurauchi]Oi Eliangela!

Então, na hora que você seta o timeout o httpclient já executou o post. Tente colocar a linha do timeout antes de chamar o execute.

Outra coisa, você está fazendo essa requisição em outra thread?[/quote]

Olá toshikurauchi!!

Obrigada pela ajuda!
eu vi que eu setei o timeout somente depois de executar o httpclient, e também vi que eu esqueci de setar o httpParams denovo!

O código ficou assim:

[code]
public static String post(String url, List<NameValuePair> dados, int timeout) throws IOException {
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, timeout);
HttpConnectionParams.setSoTimeout(httpParameters, timeout);

	HttpPost httppost = new HttpPost(url);
	DefaultHttpClient httpClient = new DefaultHttpClient();
	httppost.setEntity(new UrlEncodedFormEntity(dados));
	httpClient.setParams(httpParameters); //eu seto os params aqui... tinha me esquecido disso!

	HttpResponse response = httpClient.execute(httppost);
	HttpEntity entity = response.getEntity();
	InputStream is = entity.getContent();

	if (is == null) {
		return &quot;&quot;;
	}

	int i;
	StringBuilder stringBuilder = new StringBuilder();

	while ((i = is.read()) &gt;= 0) {
		stringBuilder.append((char) i);
	}

	return stringBuilder.toString();
}[/code]

Obrigada!

Como eu faria!

primeiramente como uma boa pratica, colocar sempre um try/catch para tratar as exception, fica ai a dica, vc pode usar um objeto do tipo Handler que serve para processar alguma coisa depois de um certo tempo, funciona com uma Thread.sleep(), ai vc configura seu handler com o delay de 1 segundo, ou vc tbm pode usar um Alarm para agendar sua rotina, fica ai a dica, da uma pesquisada sobre a classe Headler http://developer.android.com/reference/android/os/Handler.html e AlarmaManager http://developer.android.com/reference/android/app/AlarmManager.html e outra coisa vc tbm poderia delegar o envio do post para uma thread. Qualque duvida posta ai.

Legal que funcionou! :slight_smile:

E reforço que é uma boa prática fazer esses processamentos mais demorados (como as requisições web) em threads separadas, como o srmachado falou… Isso para não bloquearmos a thread principal que é reservada para a interação com o usuário (entrada e saída, atualização da tela, etc).

[quote=toshikurauchi]Legal que funcionou! :slight_smile:

E reforço que é uma boa prática fazer esses processamentos mais demorados (como as requisições web) em threads separadas, como o srmachado falou… Isso para não bloquearmos a thread principal que é reservada para a interação com o usuário (entrada e saída, atualização da tela, etc).[/quote]

Concordo com vcs nisso, e eu tenho threads que fazem essas coisas separadamente no meu programa (até coisas em segundo plano), mas nesse caso específico, a resposta tem que ser instantânea, porque é um caso onde o cliente não pode ficar esperando pela boa vontade do wireless.

Bom… try/catch tem lá, porque quando cai em timeout, dá uma exception mesmo. Daí eu trato com uma mensagem dizendo que não tem conexão disponível.
Sobre essa ideia do Handler e ficar monitorando, eu fiz um parecido pra guardar informações quando não tiver conexão, e quando o smartphone conectar, ele envia as informações pendentes pro servidor.

Pessoal, obrigada pela ajuda.
Até mais

Vc usou o esquema de Broadcastreceiver?

Eu não conhecia esse esquema (acabei de pesquisar e achei interessante), mas eu fiz assim:
criei uma Thread que é ativada quando tem algum dado pendente de envio. Essa Thread fica monitorando a cada 5 segundos se existe conexão. Caso exista ele envia os dados pro servidor.
Quando esses dados são enviados com sucesso, eu seto a flag da minha thread pra FALSE pra finalizá-la.

Vou pesquisar mais sobre o Broadcast Receiver e vou ver se implemento aqui.

Obrigada

Da uma olhada nesse post que ensino a uar o Broadcastreceiver para capturar o evento de conexão com internet:

http://guj.com.br/java/255791-android-conexao-com-mysql-e-gerenciamento-de-dados-com-xml

Qualquer duvida estamos ai.

Obrigada! vou fazer com broadcast receiver aqui :wink: