Curso Android – Android + WebServices

Como prometido no artigo anterior, o Tech-Portugal vai dar aos seus leitores as ferramentas necessárias para criar, de forma simples, uma aplicação Android a comunicar com o servidor recorrendo a WebServices.

Por termos o servidor a correr na máquina local, vamos usar o emulador do Android Studio, pois será mais fácil testar e evitar complicações no exemplo a demonstrar. Caso o leitor futuramente queira colocar o servidor a correr em rede, poderá faze-lo bastando alterar os acessos no código!

android

Servidor

A interface irá ter todos os métodos que o WebService deverá implementar. Neste caso, terá apenas a função soma.

@WebService
public interface myWSInterface {
    @WebMethod int soma(String num1, String num2);
}

Criação de uma classe myWS neste caso, que irá implementar a interface anteriormente criada. Nesta classe, iremos programar o que irá fazer o método soma ou quaisquer outros métodos que o leitor queira implementar.

package ws_android;
import javax.jws.WebService;

@WebService(endpointInterface = "ws_android.myWSInterface")
public class myWS implements myWSInterface{

    public myWS(){}
    
    @Override
    public int soma(String num1, String num2) {
        System.out.println("Recebi Algo");
        return Integer.parseInt(num1) + Integer.parseInt(num2);
    }
}

Serve apenas para criar um endpoint e publicar o WebService no ip e porto definidos.

public class Publisher {
     public static void main(String[] args)
    {
        Endpoint.publish("http://127.0.0.1:8080/ws_android",
        new myWS());
    }
}

Android App

Antes de se avançar para qualquer outro passo, o utilizador deverá criar um projeto no android studio com uma “blank activity”.

Para que o WebService funcione com pedidos SOAP, deveremos recorrer à dependência do KSOAP.  Deverá então dirigir-se ao ficheiro gradle, do módulo e, acrescentar às dependências o seguinte:

compile files('libs/ksoap2-android-assembly-2.5.2.jar')

Faça clean do projeto!

De seguida deverá realizar o download do KSOAP aqui.

Após o Download, deverá copiar o .jar da qual acabou de realizar a transferência e, deverá dirigir-se à pasta do seu projeto, seguida da pasta app e colocar o .jar dentro da pasta libs, ou seja:

“[O_SEU_PROJETO] -> app -> libs” e copiar para lá o .jar do KSOAP.

Para verificar que a dependência está correta, poderá dirigir-se a “File” -> “Project Structure” e:

Dependencias

Note-se que poderá ter realizado o download de uma versão diferente do ksoap. Na imagem acima, o ksoap usado era da versão 3.6.0, diferente do ksoap disponibilizado para download.

O layout da aplicação a usar poderá ser o seguinte:

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:weightSum="1">
        <EditText
            android:layout_width="254dp"
            android:layout_height="wrap_content"
            android:id="@+id/num1" />
        <EditText
            android:layout_width="249dp"
            android:layout_height="wrap_content"
            android:id="@+id/num2" />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Enviar"
            android:id="@+id/btnEnviar"
            android:layout_alignParentTop="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_marginTop="81dp" />
        <TextView
            android:layout_width="167dp"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:text="Large Text"
            android:id="@+id/textViewResultado"
            android:layout_weight="0.12" />
    </LinearLayout>

É importante clarificar o seguinte:

  • URL: Neste caso, a variável URL deverá ser 10.0.2.2:8080 pois estamos a correr com o emulador. Este endereço de URL é o mesmo que o localhost mas, como o emulador está a correr em máquina virtual.

O código que se segue apenas representa a acção ao evento do botão, o pedido e sucessiva resposta SOAP do servidor.

public class MainActivity extends AppCompatActivity {
    // localização do servidor
    private static final String NAMESPACE = "http://ws_android/";
    private static String URL="http://10.0.2.2:8080/ws_android?wsdl";

    // nome dos métodos a chamar e, ação a realizar
    private static final String METHOD_NAME = "soma";
    private static final String SOAP_ACTION =  NAMESPACE + METHOD_NAME;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btn = (Button)findViewById(R.id.btnEnviar);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v){
                TextView tvNum1 = (TextView)findViewById(R.id.num1);
                TextView tvNum2 = (TextView)findViewById(R.id.num2);
                // Content values com o valor dos numeros
                // chamada ao método soap
                ContentValues cv = new ContentValues();
                cv.put("num1", tvNum1.getText().toString());
                cv.put("num2", tvNum2.getText().toString());
                new SoapRequest().execute(cv);
            }
        });
    }

    // Função para atualizar vista
    private void AtualizaVista(String resultado){
        TextView tvResultado = (TextView)findViewById(R.id.textViewResultado);
        tvResultado.setText(resultado);
    }
    private class SoapRequest extends AsyncTask<ContentValues, Void, String> {

        @Override
        protected String doInBackground(ContentValues... params) {
            String result;
            SoapObject request = null;

            request = new SoapObject(NAMESPACE, METHOD_NAME);

            // get dos numeros que estavam na TextView
            String num1 = params[0].getAsString("num1");
            String num2 = params[0].getAsString("num2");

            // Passagem dos numeros para o webservice
            request.addProperty("arg0", num1);
            request.addProperty("arg1", num2);

            // Criacao de um envelope para enviar ao servidor
            // Este envelope irá conter o pedido e as variáveis da funcao soma
            SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);

            envelope.setOutputSoapObject(request);

            HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
            try {
                androidHttpTransport.call(SOAP_ACTION, envelope);

                // Obter a resposta, neste caso será a soma dos dois numeros enviados
                SoapPrimitive resultRequest = (SoapPrimitive) envelope.getResponse();
                Log.wtf("[RESPONSE]", resultRequest.toString());
                result = resultRequest.toString();
            } catch (IOException e) {
                result = "Error: " + e;
                //Log.wtf("[ERROR]", "error 1");
            } catch (XmlPullParserException e) {
                result = "Error: " + e;
            }
            Log.wtf("[RESULT]", result);
            return result;
        }

        // Atualizar a vista após a execução da AsyncTask
        protected void onPostExecute(String res) {
            // TODO: check this.exception
            // TODO: do something with the feed
            AtualizaVista(res);
        }
    }

Uma vez que a aplicação irá aceder à internet, o leitor não se deverá esquecer de dar a devida permissão:

<uses-permission android:name="android.permission.INTERNET" />

Com isto, o resultado deverá ser trivial. O programa está preparado para receber números inteiros (não existem verificações nem validações caso o utilizador insira floats ou strings).

Estás preparado? Tens dúvidas? Comenta o artigo!

Fonte das imagens