Consumindo WebService pelo Android - Dúvidas

14 respostas Resolvido
clicnet

E ai galera beleza,

Gostaria de poder contar com a ajuda de vocês, tenho um WebService Rest desenvolvido em Java o mesmo já está funcionando, a minha dúvida está na parte do Android na hora de consumir os dados do banco.

Tenho as seguintes classes:

  • UsuarioREST

public class UsuarioREST {
private static final String URL_WS = “http://10.1.1.103:8084/ServidorWS/webresources/Usuario/Usuario/get/”;

public Usuario getUsuario(int id) throws Exception {

 String[] resposta = new Webservice().get(URL_WS+id);
 
 if (resposta[0].equals("200")) {
     Gson gson = new Gson();
     Usuario usuario = gson.fromJson(resposta[1], Usuario.class);
     return usuario;
 } else {
     throw new Exception(resposta[1]);
 }
}

}

  • HttpClient

private static final int JSON_CONNECTION_TIMEOUT = 3000;

private static final int JSON_SOCKET_TIMEOUT = 5000;

private static HttpClient instance;

private HttpParams httpParameters ;

private DefaultHttpClient httpclient;
private void setTimeOut(HttpParams params){
     HttpConnectionParams.setConnectionTimeout(params, JSON_CONNECTION_TIMEOUT);
     HttpConnectionParams.setSoTimeout(params, JSON_SOCKET_TIMEOUT);
    }
    
    private HttpClient() {
     httpParameters = new BasicHttpParams();
     setTimeOut(httpParameters);
     httpclient = new DefaultHttpClient(httpParameters);
    }
    
    public static DefaultHttpClient getHttpClientInstace(){
     if(instance==null)
         instance = new HttpClient();
     return instance.httpclient;
    }
  • Webservice

public final String[] get(String url) {

String[] result = new String[2];
    

     try {
    	 HttpGet httpget = new HttpGet(url);
	     HttpResponse response;
         response = HttpClient.getHttpClientInstace().execute(httpget);
         entity = response.getEntity();

         if (entity != null) {
             result[0] = String.valueOf(response.getStatusLine().getStatusCode());
             InputStream instream = entity.getContent();
             result[1] = toString(instream);
             instream.close();
             Log.i("get", "Result from post JsonPost : " + result[0] + " : " + result[1]);
         }
     } catch (Exception e) {
         Log.e("NGVL", "Falha ao acessar Web service", e);
         result[0] = "0";
         result[1] = "Falha de rede!";
     }
     return result;
    }
  • MainActivity

buscarIdBtn.setOnClickListener(new View.OnClickListener() {

@Override
        public void onClick(View v) {
        	id = idEdt.getText().toString();
            UsuarioREST rest = new UsuarioREST();
            try {
                Usuario usuario = rest.getUsuario(Integer.parseInt(id));
                txtView.setText(usuario.toString());
            } catch (NumberFormatException e) {
                e.printStackTrace();
                gerarToast("Digite um ID válido!");
            } catch (Exception e) {
                e.printStackTrace();
                gerarToast(e.getMessage());
            }
        }
    });

Essas são minhas classes no cliente android.
Gostaria de executar um GET e pegar dados de uma tabela que estão no banco, o erro que está aparecendo está na classe “Webservice”. segue o erro: “Falha ao acessar Web service”.
O que vocês acham que pode ser.

14 Respostas

me1

O primeira coisa que deve ser feito é alterar a seguinte linha:

Para:

Log.e(“NGVL”, e.getMessage(), e);

Pois a mensagem “Falha ao acessar Web service” é sua e não representa o erro em si.

Depois que vc fizer isso roda a aplicação e posta o erro que será impresso.

igomes

Se vc não jogar a exception fica difícil né ?

clicnet

Retornou “null”.

Segue o log:

03-16 14:57:26.387: E/NGVL(984): null

03-16 14:57:26.387: E/NGVL(984): android.os.NetworkOnMainThreadException

03-16 14:57:26.387: E/NGVL(984): 	at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)

03-16 14:57:26.387: E/NGVL(984): 	at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)

03-16 14:57:26.387: E/NGVL(984): 	at libcore.io.IoBridge.connectErrno(IoBridge.java:144)

03-16 14:57:26.387: E/NGVL(984): 	at libcore.io.IoBridge.connect(IoBridge.java:112)

03-16 14:57:26.387: E/NGVL(984): 	at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)

03-16 14:57:26.387: E/NGVL(984): 	at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)

03-16 14:57:26.387: E/NGVL(984): 	at java.net.Socket.connect(Socket.java:842)

03-16 14:57:26.387: E/NGVL(984): 	at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:119)

03-16 14:57:26.387: E/NGVL(984): 	at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:144)

03-16 14:57:26.387: E/NGVL(984): 	at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)

03-16 14:57:26.387: E/NGVL(984): 	at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)

03-16 14:57:26.387: E/NGVL(984): 	at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)

03-16 14:57:26.387: E/NGVL(984): 	at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)

03-16 14:57:26.387: E/NGVL(984): 	at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)

03-16 14:57:26.387: E/NGVL(984): 	at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)

03-16 14:57:26.387: E/NGVL(984): 	at com.android.ws.Webservice.get(Webservice.java:32)

03-16 14:57:26.387: E/NGVL(984): 	at com.android.apptoner.UsuarioREST.getUsuario(UsuarioREST.java:12)

03-16 14:57:26.387: E/NGVL(984): 	at com.android.activity.MainActivity$1.onClick(MainActivity.java:49)

03-16 14:57:26.387: E/NGVL(984): 	at android.view.View.performClick(View.java:4202)

03-16 14:57:26.387: E/NGVL(984): 	at android.view.View$PerformClick.run(View.java:17340)

03-16 14:57:26.387: E/NGVL(984): 	at android.os.Handler.handleCallback(Handler.java:725)

03-16 14:57:26.387: E/NGVL(984): 	at android.os.Handler.dispatchMessage(Handler.java:92)

03-16 14:57:26.387: E/NGVL(984): 	at android.os.Looper.loop(Looper.java:137)

03-16 14:57:26.387: E/NGVL(984): 	at android.app.ActivityThread.main(ActivityThread.java:5039)

03-16 14:57:26.387: E/NGVL(984): 	at java.lang.reflect.Method.invokeNative(Native Method)

03-16 14:57:26.387: E/NGVL(984): 	at java.lang.reflect.Method.invoke(Method.java:511)

03-16 14:57:26.387: E/NGVL(984): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)

03-16 14:57:26.387: E/NGVL(984): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)

03-16 14:57:26.387: E/NGVL(984): 	at dalvik.system.NativeStart.main(Native Method)

03-16 14:57:26.399: W/System.err(984): java.lang.Exception: Falha de rede!

03-16 14:57:26.417: W/System.err(984): 	at com.android.apptoner.UsuarioREST.getUsuario(UsuarioREST.java:19)

03-16 14:57:26.417: W/System.err(984): 	at com.android.activity.MainActivity$1.onClick(MainActivity.java:49)

03-16 14:57:26.417: W/System.err(984): 	at android.view.View.performClick(View.java:4202)

03-16 14:57:26.417: W/System.err(984): 	at android.view.View$PerformClick.run(View.java:17340)

03-16 14:57:26.428: W/System.err(984): 	at android.os.Handler.handleCallback(Handler.java:725)

03-16 14:57:26.428: W/System.err(984): 	at android.os.Handler.dispatchMessage(Handler.java:92)

03-16 14:57:26.428: W/System.err(984): 	at android.os.Looper.loop(Looper.java:137)

03-16 14:57:26.428: W/System.err(984): 	at android.app.ActivityThread.main(ActivityThread.java:5039)

03-16 14:57:26.428: W/System.err(984): 	at java.lang.reflect.Method.invokeNative(Native Method)

03-16 14:57:26.428: W/System.err(984): 	at java.lang.reflect.Method.invoke(Method.java:511)

03-16 14:57:26.438: W/System.err(984): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)

03-16 14:57:26.438: W/System.err(984): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)

03-16 14:57:26.448: W/System.err(984): 	at dalvik.system.NativeStart.main(Native Method)

03-16 14:57:27.128: E/SurfaceFlinger(36): ro.sf.lcd_density must be defined as a build property
igomes

da um e.toString(); no lugar do e.getMessage();
Mas ao que parece pelo stack trace, ele não ta batendo la no ws.
Já testou a url no postman ?
http://10.1.1.103:8084/ServidorWS/webresources/Usuario/Usuario/get/1 por ex
E precisa ver o http code retornado resposta[0]
E outra coisa inverta sua comparação, se sua resposta[0] vier null, nullpointerexception
"200".equals(resposta[0])

me1

O problema é que você está tentando consultar o web service na UI Thread, você deve usar no mínimo um AsyncTask.
Descrição do erro:
http://developer.android.com/intl/pt-br/reference/android/os/NetworkOnMainThreadException.html

O Link abaixo tem a solução para o seu problema em português:

clicnet

Dei uma lida no link que você mandou, só não entendi de que forma vou chamar essa classe no meu projeto.

Segue a classe:

public class Consulta extends AsyncTask<String, Void, Boolean> {

@Override
protected Boolean doInBackground(String... params) {

    String URL = "http://10.1.1.103:8084/ServidorWS/webresources/Usuario/Usuario/get";
    String linha = "";
    Boolean Erro = true;

    if (params.length > 0)
        // faço qualquer coisa com os parâmetros

        try {

            HttpClient client = new DefaultHttpClient();
            HttpGet requisicao = new HttpGet();
            requisicao.setHeader("Content-Type",
                    "text/plain; charset=utf-8");
            requisicao.setURI(new URI(URL));
            HttpResponse resposta = client.execute(requisicao);
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    resposta.getEntity().getContent()));
            StringBuffer sb = new StringBuffer("");

            while ((linha = br.readLine()) != null) {
                sb.append(linha);
            }

            br.close();

            linha = sb.toString();
            Erro = false;

        } catch (Exception e) {
            Erro = true;
        }

    return Erro;
}

}

me1
Solucao aceita

Seu código deve ficar mais ou menos assim:

@Override
public void onClick(View v) {
    int id = idEdt.getText().toString();

    AsyncTask<Integer, Void, Usuario> atBuscaUsuario = new AsyncTask<Integer, Void, Usuario>() {

        ProgressDialog progressDialog;

        @Override
        protected Usuario doInBackground(Integer... params) {
            try {
                UsuarioREST rest = new UsuarioREST();
                Usuario usuario = rest.getUsuario(Integer.parseInt(params[0]));
                return usuario;

            } catch (NumberFormatException e) {
                e.printStackTrace();
                gerarToast("Digite um ID válido!");
                
            } catch (Exception e) {
                e.printStackTrace();
                gerarToast(e.getMessage());
            }

            return null;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            progressDialog = ProgressDialog.show(getActivity(), "Aguarde", "Buscando usuario...");
        }

        @Override
        protected void onPostExecute(Usuario usuario) {
            super.onPostExecute(usuario);

            if (usuario != null) {
                txtView.setText(usuario.toString());
            }

            progressDialog.dismiss();
        }
    };
    atBuscaUsuario.execute(id);
}

/**
 * 
 * Forca a exibicao de uma mensagem fora da UI Thread (MainThread)
 * 
 * @param msg
 */
private void gerarToast(final String msg) {
    getActivity().runOnUiThread(new Runnable() {
        @Override
        public void run() {
            Toast.makeText(getActivity(), msg, Toast.LENGTH_LONG).show();
        }
    });
}
clicnet

Tive duas dúvidas nesse código que você mandou:

1º Esse “id” do tipo “int”, no caso na tela do android ele recebe uma String nesse caso ai deu erro.

2º Eu preciso criar uma classe com o método “getActivity()”?

me1

Esqueci de fazer o cast no campo id:

1º    int id = Integer.parseInt(idEdt.getText().toString());
        2º    Esse "getActivity()" é o contexto de onde você está chamando o método, se vc estiver chamando apartir de uma Activity vc deve chamar SuaActivity.this, se vc estivesse chamando apartir de uma fragment vc deveria chamar getActivity(), entendeu?
clicnet

Valeu ai cara, os dois ítens foram solucionados com suas dicas agora ficou um erro nessa linha:

Usuario usuario = rest.getUsuario(Integer.parseInt(params[0]));

Disse que o método parseInt (String) não é aplicado para o argumento Integer.

me1

Não precisa fazer o cast, deixa o código assim:

clicnet

Deu certo, agora vou testar o app pra ver se fluiu.
Desde já agradeço.

clicnet

Agora deu certo.

Muitíssimo abrigado não sei nem como lhe agradecer, já estava com quase uma semana batendo nesse erro. Agora fluiu.

me1

É nóis. qualquer coisa posta aí.

Criado 16 de março de 2016
Ultima resposta 16 de mar. de 2016
Respostas 14
Participantes 3