Acessando a Rede no Android

Nesse artigo, cuja base é descrita no artigo “Develop Android applications with Eclipse“, explora os recursos de acesso a rede do Android. Vamos ver como tirar vantagem das opções de acesso a rede do Android de forma útil. A plataforma Android é ideal para desenvolvedores Java: eles podem usar as suas habilidades existentes para prover conectividade de rede para um celular ou plataforma embutida.

Recursos de acesso a rede do Android

O Android é baseado no kernel Linux e contém um bom conjunto de  recursos de rede. Se você ainda não instalouo SDK do Android, pode queres baixa-lo e dessa forma poder acompanhar os exemplos

A tabela 1 motra alguns pacotes relacionados a acesso a rede do SDK do Android.

Tabela 1

Pacote Descrição
java.net Provides networking-related classes, including stream and datagram sockets, Internet Protocol, and generic HTTP handling. This is the multipurpose networking resource. Experienced Java developers can create applications right away with this familiar package.
java.io Though not explicitly networking, it’s very important. Classes in this package are used by sockets and connections provided in other Java packages. They’re also used for interacting with local files (a frequent occurrence when interacting with the network).
java.nio Contains classes that represent buffers of specific data types. Handy for network communications between two Java language-based end points.
org.apache.* Represents a number of packages that provide fine control and functions for HTTP communications. You might recognize Apache as the popular open source Web server.
android.net Contains additional network access sockets beyond the core java.net.* classes. This package includes the URI class, which is used frequently in Android application development beyond traditional networking.
android.net.http Contains classes for manipulating SSL certificates.
android.net.wifi Contains classes for managing all aspects of WiFi (802.11 wireless Ethernet) on the Android platform. Not all devices are equipped with WiFi capability, particularly as Android makes headway in the “flip-phone” strata of cell phones from manufacturers like Motorola and LG.
android.telephony.gsm Contains classes required for managing and sending SMS (text) messages. Over time, an additional package will likely be introduced to provide similar functions on non-GSM networks, such as CDMA, or something like android.telephony.cdma.

A lista acima não é exaustiva, mas foi feita para lhe fornecer uma visãogeral do que a plataforma é capaz de fazer. A próxima seção explora alguns exemplos relacionados a acesso a rede.

Exemplo de acesso a rede simples

Para demonstrar quão fácil é conectar-se a rede no Android, o exemplo abaixo mostrará como pegar um texto de uma página web. Baixe o código-fonte do exemplo. A figura 1 demonstra a aplicação em execução.
Figura 1

Essa seção fornece o código necessário para construir a aplicação exemplo. Iremos agora dar uma olhada em aspectos da interface, e depois cobriremos o código relacionado ao acesso a rede.

Existem três elementos da interface:

  • EditText permite ao usuário informar uma URL (http://developer.android.com é exibida na Figura 1 e na Listagem 2).
  • Um botão é usado para dizer ao programa para buscar o texto da página web.
  • Depois que os dados são recebidos, é exibido em uma TextView.

A listagem 1 mostra o arquivo main.xml, que é a interface completa dessa aplicação.
Listagem 1. main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<EditText
android:layout_height="wrap_content"
android:id="@+id/address"
android:layout_width="fill_parent"
android:text="http://google.com"
>
</EditText>
<Button
 android:id="@+id/ButtonGo"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="go!"
 >
</Button>
<TextView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#ffffff"
    android:textColor="#000000"
	android:id="@+id/pagetext"
    />
</LinearLayout>

A listagem 2 mostra o código Java desse exemplo.
Listagem 2. GetWebPage.java

package com.msi.getwebpage;

import android.app.Activity;
import android.os.Bundle;
// used for interacting with user interface
import android.widget.Button;
import android.widget.TextView;
import android.widget.EditText;
import android.view.View;
// used for passing data
import android.os.Handler;
import android.os.Message;
// used for connectivity
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;

public class GetWebPage extends Activity {
    /** Called when the activity is first created. */

    Handler h;

	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        final EditText eText = (EditText) findViewById(R.id.address);
        final TextView tView = (TextView) findViewById(R.id.pagetext);

        this.h = new Handler() {

            @Override
            public void handleMessage(Message msg) {
                // process incoming messages here
                switch (msg.what) {
                    case 0:
                    	tView.append((String) msg.obj);
                    	break;
                }
                super.handleMessage(msg);
            }
        };
        final Button button = (Button) findViewById(R.id.ButtonGo);
        button.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View v) {
            	try	{
            		tView.setText("");
                // Perform action on click
                	URL url = new URL(eText.getText().toString());
                    URLConnection conn = url.openConnection();
                    // Get the response
                    BufferedReader rd = new BufferedReader(new
InputStreamReader(conn.getInputStream()));
                    String line = "";
                    while ((line = rd.readLine()) != null) {
                		Message lmsg;
                        lmsg = new Message();
                        lmsg.obj = line;
                        lmsg.what = 0;
                        GetWebPage.this.h.sendMessage(lmsg);
                    }
            	}
            	catch (Exception e)	{
            	}
            }
        });
    }
}

O código pode ser quebrado em algumas áreas. Existem várias (e necessárias) setenças para referenciar adequadamente a interface, passagem de dados, e classes relacionadas ao acesso a rede em uso na aplicação. Todo o código relacionado ao acesso a rede é colocado dentro do método OnClick de OnClickListener. Ele é invocado quando o botão é selecionado.

As classes URL e URLConnection juntam-se para fornecer a conectividade a um site web que o usuário escolhe. Uma instância de BufferedReader cuida de ler os dados vindos da conexão ao site. A medida que cada linha é lida, o texto é anexado a TextView. Os dados não são simplesmente associados ao TextView diretamente (apesar de poder ser nesse exemplo). Aqui apresentamos o padrão de criação de objetos mensageiros e passar esse objeto para uma instância de um manipulador (handler). Esse é o melhor jeito de atualizar a interface, particularmente em aplicações reais onde várias threads podem estar sendo executadas ao mesmo tempo.

No exemplo, a aplicação Android está se comunicando com um servidor Web HTTP, como o Apache ou IIS. Se a aplicação precisar se comunicar diretamente a um socket TCP, ao invés do HTTP, você deve implementar a aplicação diferentemente. A listagem 3 é um código que mostra outra forma de interagir com um servidor remoto. A listagem é implementada em uma thread separada.
Listagem 3.

    public class Requester extends Thread {
        Socket requestSocket;
        String message;
        StringBuilder returnStringBuffer = new StringBuilder();
        Message lmsg;
        int ch;
        @Override
        public void run() {
            try {
                this.requestSocket = new Socket("remote.servername.com", 13);
                InputStreamReader isr = new InputStreamReader(this.requestSocket.
getInputStream(), "ISO-8859-1");
                while ((this.ch = isr.read()) != -1) {
                    this.returnStringBuffer.append((char) this.ch);
                }
                this.message = this.returnStringBuffer.toString();
                this.lmsg = new Message();
                this.lmsg.obj = this.message;
                this.lmsg.what = 0;
                h.sendMessage(this.lmsg);
                this.requestSocket.close();
            } catch (Exception ee) {
                Log.d("sample application", "failed to read data" + ee.getMessage());
            }
        }
    }

Como no exemplo anterior, o código acimam usa a abordagem de mensagens e manipulador para enviar os dados ao solicitante, para atualização da interface e processamento subsequente. Ao contrário do exemplo da listagem 1, esse exemplo não está se comunicando com um servidor HTTP, dessa froma não usa a classe URLConnection. Ao invés disso, usa a classe de baixo nível Socket que abre uma conexão com um servidor remoto na porta 13. A porta 13 é a porta da aplicação “Servidor de data e hora”.

O servidor de data de hora aceita uma conexão vinda de um socket e envia a data e hora em um formato textual de volta. Depois que os dados são enviados, o socket é fechado pelo servidor. O exemplo tamém demonstra o uso de um InputStreamReader e uma codificação de caracteres específicas.

Enviar uma mensagem de texto é outra tarefa que você possivelmente irá precisar fazer com o Android. A listagem 4 mostra um exemplo.
Listagem 4.

void sendMessage(String recipient,String myMessage) {
 SmsManager sm = SmsManager.getDefault();
 sm.sendTextMessage("destination number",null,"hello there",null,null);
}

O processo de envio de uma mensagem de texto é bem direto. Primeiro, obtemos uma referência para SmsManager usando o método estático getDefault(). Depois invocamos o método sendTextMessage. Os argumentos:

Número de telefone do recipiente
Incui o código de área.
Número de telefone da central de serviço
Usando o valor null significa que você está satisfeito com a central de serviços padrão para processamento de mensagens. Na maioria, senão todas as aplicações, usaremos o valor null para esse parâmetro.
Sua carga de pagamento
Mantenha o tamanho da mensagem com menos de 160 bytes, a menos que esteja de acordo com os dados sendo divididos em múltiplas mensagens.
Objetivo (Intent) pendente
Um objetivo (intent) pendente será iniciado quando a mensagem é enviada ou um erro ocorre. Passamos o valor null para esse parâmetro se essa notificação não for necessária. (Veja Resources para obter mais informações sobre objetivos (intents) e os fundamentos do Android).
Objetivo (Intent) de destino
Um objetivo (intent) oopcional pode ser iniciado quando a confirmação do recebimento é entregue. Podemos passar o valor null para esse parâmetro se essa notificação não for importante.

Tanto para conexão a uma página web quanto a uma aplicação TCP personalizada, a plataforma Android estará pronta para lhe ajudar. Como mostrado na listagem 4, o envio de uma mensagem de texto é bem fácil. Usando os parâmetros opcionais para os objetivos (intents), você pode mesmo executar alguma ação quando as mensagens forem enviadas e entregues. Esse recurso não está disponíveis em todas as plataformas móveis.

Exame de um sistema de monitoramente do ambiente

Para esse cenário, vamos assumir que você é o gerente de vários escritórios onde sua empresa reside. Gerenciar propriedade não é muito diferente de gerenciar um data center – longos períodos de calmaria interrompidos por periodos de turbulência.

Em um dia aleatório, você pode ter que supervisionar uma operação de limpeza depois de um aquecedor de água de 10 anos de idade vazar em todo um armário cheio de PCs velhos e manuais de treinamento. Felizmente, você estava na cidade. Se você tivesse viajado, a situação teria sido realmente feia. Este acidente, e outros como ele, inspirou a idéia de explorar o uso do Android para auxiliar no monitoramento da condição da propriedade. A Figura 2 é um diagrama de blocos de alto nível de um tal sistema.
Figure 2. High-level block diagram of monitoring system

A arquitetura é uma abordagem tradicional usando um micro-controlador para interagir com alguns sensores simples que coletam dados. Os dados são então enviados para um controlador com um protocolo de comunicações serial, como RS232 e RS485. O controlador se parece com um PC ou máquina similar. Esses dados podem então ser acessados através da Internet através de um firewall. O protocolo usado entre o telefone Android pode ser desde o HTTP até um esquema proprietário.

Os dados enviados entre o controlador e o dispositivo Android devem ter a seguinte representação básica de bytes:

  • A presença de água
  • A temperatura atual
  • Quanta energia está sendo consumida
  • Talvez alguns valores analógicos e digitais de propósito geral

Por que você deve se importar com o consumo de energia? Uma razão para isso seria simplesmente controlar quem deixa a luz ligada, aumentando o gasto com eletricidade. Uma segunda razão pode ser um pouco mais problemática: vamos dizer que você possui um freezer grande e a energia cai. Isso poderia causar sérios problemas para muitos negócios. Ou, talvez, ocorra algum curto-circuito em sua unidade de condicionamento de ar e a sala dos computadores começaria a esquentar demasiadamente.

A arquitetura básica da aplicação parece trabalhável. Nos termos do desenvolvimento Android, você poderia substituir o Android na figura 2 por qualquer outra plataforma móvel. Mas o que aconteceria se você trocasse o micro-controlador por um equipamento com Android? A próxima seção discute como expandir a aplicação e quais recursos poderiam ser adicionados por trazer o Android para uma posição mais proeminente no esquema.

Expandindo a aplicação

O primeiro esquema esse artigo é centralizado em torno de um micro-controlador. Os micro-controladores vem em várias formas e tamanhos, de um “10F” com 6 pinos até um microchip de 32-bits com vários periféricos, pinos e espaço. O que acontece se você coloca-se um dispositivo Android no lugar de um micro-controlador tradicional? Para algumas aplicações, isso poderia ser inviável devido ao custo, mas tente ver as possibilidades dessa abordagem a medida que contempla o esquema da figura 3.
Figure 3.

O carregamento do Android no lado embutido da figura permite que você trabalhe com um ambiente altamente programável. Você pode continuar a monitorar a umidade, temperatura e consumo de energia, mas agora pode também analisar gravações de áudio, vídeo e vibrações. Podem ter um mini alarme, um sistema de controle de acesso e uma ferramenta de monitoramento ambiental. Como o Android é complemento preparado para acessar a rede, você pode fazer tudo isso sem um computador pessoal e comunicar essas informações diretamente a rede.

Android is running primarily on mobile phones today, but it has been ported to NetBooks and other platforms. Hopefully this article has given you some food for thought. I’ve got to go and get my system running. You never know when another water heater is going to leak.

O Android roda primariamente em telefones celulares hoje, mas tem sido portado para netBooks e outras plataformas. Essse artigo pode lhe dar bastante munição para pensar em novos usos.

Sumário

Nesse artigo, vimos como acessar a rede no Android. Vimos alguns exemplos de aplicações que podem ser criadas, incluindo interação com uma página web e envio de mensagens de texto. Vimos como o Android pode ser conectado a um sistema real para monitoração ambiental.

Download

Descrição Nome Tam Método de download
GetWebPage source code os-android-networking_GetWebPage.zip 14KB HTTP

 

Recursos

Traduzido de www.ibm.com/developerworks