domingo, 22 de abril de 2012

Programar para Android - 05


Try03 - Layout com código Java.

Vamos agora tentar o mesmo layout, mas usando apenas Java.
Vamos criar o projeto Try03, e abrimos o Try03Activity.java, main.xml e strings.xml.
Primeiro vamos analisar o conteúdo.


package pt.omeusite.try03;


import android.app.Activity;
import android.os.Bundle;


public class Try03Activity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

A identificação do package e os imports são o normal do Java.
Apenas está definida a classe Try03Activity que extends a classe Activity. Dentro da nossa classe apenas temos um método onCreate(), que faz o override do onCreate() da classe Activity. O método onCreate() é chamado cada vez que uma atividade é criada, por isso é o local ideal para colocar o código que constrói a atividade (é como se fosse o construtor do objeto). A primeira ação é chamar o onCreate() da classe pai, passando-lhe o Bundle savedInstanceState. Deixemos a explicação do que é este Bundle para mais tarde. Fiquemos só com a noção que precisa estar lá.

A única outra instrução é um enigmático setContentView(R.layout.main), O setContentView() define qual é a view desta atividade (uma View, recordemos é um widget ou um layout), ou seja define o que vai aparecer no écrã. Neste caso passamos-lhe o argumento R.layout.main. O objeto R refere-se à diretoria res, o layout.main é uma referência ao ficheiro main.xml na diretoria layout. Ou seja, vai ler o nosso velho amigo main.xml! Por isso é que quando editamos o main.xml as alterações aparecem no écrã!
Percebido isto, vamos começar a apagar coisas:

  • no Try03Activity.java apagamos exatamente a linha setContentView(R.layout.main);
  • no main.xml apagamos a TextView;
  • no strings.xml apagamos a string hello.
Ficamos com uma aplicação que nada faz (semelhante ao que fizemos em Try00, mas agora há mais algum código no ficheiro .java).
A partir de agora não mexemos mais nos ficheiros XML.
O ficheiro .java fica assim:

package pt.omeusite.try03;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;

public class Try03Activity extends Activity {
    // estas views vão ser necessárias
    LinearLayout vLayout, hLayout;
    TextView tvTitle, tvName;
    EditText etEdit;
    Button btOk;

/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        /* estes layouts cumprem a mesma função do:
         * android:layout_width="..."
         * android:layout_height="..."
         */
        LinearLayout.LayoutParams lpFF = new LinearLayout.LayoutParams(
                LayoutParams.FILL_PARENT,
                LayoutParams.FILL_PARENT);
        LinearLayout.LayoutParams lpFW = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.FILL_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT);
        // esta layout acrescenta o valor 1.0f, que é o peso relativo da view
        LinearLayout.LayoutParams lpWW = new LinearLayout.LayoutParams(
        LinearLayout.LayoutParams.WRAP_CONTENT,
        LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f);
        
        // criamos o layout vertical que será o topo da view
        vLayout = new LinearLayout(this);
        // definimos orientação como vertical
        vLayout.setOrientation(LinearLayout.VERTICAL);
        // definimos os parametros de layout como FILL_PARENT, FILL_PARENT
        vLayout.setLayoutParams(lpFF);

        // criamos uma nova TextView
        tvTitle = new TextView(this);
        // definimos o texto
        tvTitle.setText("Try03Activity");
        // definimos os parâmetros de layout
        tvTitle.setLayoutParams(lpFW);
        // adicionamos esta View ao layout vertical
        vLayout.addView(tvTitle);

        // criamos um novo layout
        hLayout = new LinearLayout(this);
        // definimos layout horizontal
        hLayout.setOrientation(LinearLayout.HORIZONTAL);
        // definimos os parâmetros
        hLayout.setLayoutParams(lpFW);
        
        // criamos uma nova TextView
        tvName = new TextView(this);
        // definimos o texto
        tvName.setText("Nome");
        // definimos os parâmetros
        tvName.setLayoutParams(lpWW);
        // adicionamos a View ao layout horizontal
        hLayout.addView(tvName);
       
        // criamos uma nos caixa de texto
        etEdit = new EditText(this);
        // definimos tamanho como 10 ems
        etEdit.setEms(10);
        // definimos layout
        etEdit.setLayoutParams(lpWW);
        // adicionamos ao layout horizontal
        hLayout.addView(etEdit);
       
        // adicionamos o layout horizontal ao vertical
        vLayout.addView(hLayout);
        
        // criamos um botão
        btOk = new Button(this);
        // definimos o texto
        btOk.setText("Ok");
        // definimos os parâmetros
        btOk.setLayoutParams(lpFW);
        // adicionamos o botão ao layout vertical
        vLayout.addView(btOk);
       
        // definimos a vista ativa como sendo o layout vertical que acabámos de definir
        // e o layout é mostrado no écrã
        setContentView(vLayout);
    }
}

Acho que não há melhor motivação para usar o editor gráfico ou o XML.
O programa continua a não fazer absolutamente nada, mas foi preciso escrever uma quantidade considerável de código para isso. Mesmo com as ajudas do Eclipse (Ctrl+Shift+O para adicionar os imports automaticamente e Ctrl+Space para ajudar na conclusão das palavras) não é um exercício trivial.
Por isso normalmente as interfaces gráficas não são criadas usando código. Há alturas em que é inevitável, como por exemplo preencher uma lista pendente (Spinner, na nomenclatura Android) com dados retirados de uma base de dados.

Apesar de funcionar, o programa tem um erro conceptual: as strings estão hardcoded na atividade, o que já tínhamos dito que não se deve fazer. Para usar os id das strings é preciso primeiro criá-las no ficheiro strings.xml (ou noutro ficheiro XML, não é obrigatório ser no strings.xml).
Afinal sempre temos de editar o XML. Criamos então as seguintes strings no strings.xml, usando o editor ou diretamente no XML:

<string name="tvTitle">Try02Activity</string>
<string name="tvName">Nome</string>
<string name="btOk">Ok</string>

Notar que para identificador de cada string foi usado o mesmo nome que para o objeto no código Java. Isto NÃO é obrigatório, mas ajuda a manter a sanidade do programador.

Agora precisamos alterar as linhas do código que se referem às strings:

(...)
tvTitle.setText(getString(R.String.tvTitle));
(...)
tvName.setText(getString(R.string.tvName));
(...)
btOk.setText(getString(R.string.btOk));
(...)

E pronto, um programa que não faz nada, mas arrumadinho.

Programar para Android - 04


Try02 - Layout com XML.

Vamos criar um layout exatamente idêntico ao criado no Try01, mas usando apenas os ficheiros XML diretamente.

Começamos por criar um projeto Android chamado Try02.
Por uma questão de criação de bons hábitos vamos abrir os ficheiros Try02Activity.java, res/layout/main.xml e res/values/strings.xml, mas na verdade nem sequer vamos mexer no .java.
Mudamos o main.xml e strings.xml para a vista de XML.

Ao contrário do modo de edição gráfico, em que vamos fazendo as coisas à medida que nos lembramos, do tipo "ah, preciso aqui duma string, click direito e adiciono-a", o modo XML exige que se pense um pouco antes de começar a editar.
Neste caso já sabemos bem o que pretendemos, por isso podemos ir diretamente ao ficheiro strings.xml e adicionar as strings que precisamos, que são:

  • uma string tvName com o valor "Nome", para aparecer como legenda de uma caixa de texto;
  • uma string btOk com o valor "Ok", para aparecer no botão.
A estrutura do strings.xml é bastante simples de perceber e para adicionar as duas strings basta acrescentar duas linhas dentro do resources ... /resources. Fica assim (as linhas adicionadas estão a negrito):

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="hello">Try02Activity</string>
    <string name="app_name">Try02</string>
    <string name="tvName">Nome</string>
    <string name="btOk">Ok</string>

</resources>

Também mudamo a mensagem de "Hello World" para aparecer apenas o nome da atividade.

O main.xml já dá mais um pouco de trabalho, mas nada de muito difícil.
Temos de pensar primeiro na estrutura que queremos criar. No topo tem de existir sempre um layout, que no nosso caso é um LinearLayout vertical. Dentro dele vamos colocando os outros elementos e outros layouts. Assim:
  • LinearLayout vertical
    • TextView "Try02Activity"
    • LinearLayout horizontal
      • TextView "Nome"
      • TextField editText1
    • Botão "Ok"
O main.xml criado pelo Eclipse já tem o layout vertical e a primeira TextView, só temos de acrescentar o resto, usando o que já lá está como guia (as linhas acrescentadas estão a negrito):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/tvName" />

        <EditText
            android:id="@+id/editText1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:ems="10" />

    </LinearLayout>

    <Button
        android:id="@+id/button1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/btOk" />

</LinearLayout>

Algumas coisas são óbvias, outras nem por isso.

Um elemento <LinearLayout> precisa sempre de um </LinearLayout> a fechar, porque um layout pode conter um número indeterminado de elementos, mas um elemento TextView, EditText, Button, etc não precisa da tag a fechar.

Todos os elementos (layouts ou não) precisam de pelo menos as propriedades android:layout_width e android:layout_height definidas. O valor fill_parent indica que o elemento deve estender-se para encher a área disponível no elemento "pai". O valor wrap_content indica que o elemento deve ocupar apenas o espaço necessário.

Os elementos gráficos precisam de um android:id. Observamos que todos os id aqui presentes começam com um @ e que as views (é como são conhecidos os widgets no Android) têm um @+, enquanto que as strings têm um @ sozinho.
O @ indica que não queremos que o que está escrito dentro das "" seja escrito literalmente, mas que seja procurada a referência nos recursos (ou seja algures em res/). No caso das strings o @string/btOk significa "procura nas strings uma com o id btOk". No caso das views o @+id/button1 significa "cria um identificador para esta view chamado button1". Ou seja o + é usado para criar um novo id. Se houver mais tarde uma nova referência a este botão bastaria usar @id/button1.
Também é possível referenciar recursos disponibilizados pelo próprio Android com @android:id/qq_coisa, mas lá iremos.

Se os elementos tiverem algum conteúdo de texto este é definido com android:text. Podemos fazer uma pequena experiência que é acrescentar a linha android:text="Escreva o seu nome" ao EditText. Se corrermos agora a aplicação aparece o texto "Escreva o seu nome" na caixa de edição. Já sabemos que não é boa ideia ter strings hardcoded na aplicação, por isso se quisermos realmente que apareça uma mensagem devemos criar uma string no strings.xml e colocar aqui o seu id.

A propriedade android:ems="10" do EditText parece um pouco mais obscura. Define a largura mínima do campo, que neste caso é de 10 ems. E o que é um "ems"? É a largura da letra mais larga, que é a letra "M", daí o nome. Ou seja, é o número de M's que cabem no campo.

E cá está, mais um programa que não faz nada, sem escrever uma única linha de código.

Programar para Android - 03


Try01 - Layout com o editor gráfico.

Vamos fazer mais uns TryXX até conseguirmos fazer um programa que realize algum trabalho útil (se bem que não muito) lá pelo Try07.

Android usa intensamente o interface gráfico, por isso alguma forma haverá de definir o interface gráfico de uma atividade. Na verdade existem 3 formas: usando métodos Java, usando ficheiros XML e usando o editor de interface gráfica incluído no Eclipse. É claro que o editor do Eclipse é o mais fácil de usar, mas por vezes temos de usar um dos outros métodos. Se, por exemplo, a informação que queremos mostrar é obtida em runtime temos de usar o Java para definir os elementos gráficos.

Neste try vamos começar por usar o editor do Eclipse. Criamos um novo projeto Try01. O Eclipse cria o Hello World do costume. Tipicamente há 3 ficheiros que vamos usar muito: o .java da atividade, o res/value/strings.xml e o res/layout/main.xml, por isso podemos começar por abrir os três.
Já usámos estes três ficheiros no Try00, mas aí limitamo-nos a apagar coisas.

No editor visual do main.xml, vemos uma grande quantidade de informação, o que ao princípio pode ser intimidante.
No lado direito temos uma janela "Outline", que apresenta todos os elementos gráficos, organizados em árvore. Cada elemento gráfico fica dentro de um "layout". O pré-definido é o layout linear vertical (LinearLayout, que é vertical vê-se porque o ícone ao lado apresenta umas caixas empilhadas verticalmente). Há vários (neste momento 8) tipos de layout, mas quase sempre se usam apenas o LinearLayout vertical e horizontal. É possível (e muito comum) colocar um layout dentro de outro layout.
Na janela do main.xml propriamente dito temos dois separadores na base (estilo separadores do Excel) onde podemos ver o Graphical Layout ou XML do ficheiro. Neste try vamos ficar pelo graphical layout, mas podemos sempre dar uma olhadela ao XML, para ver como fica.
Este try não faz nenhum trabalho útil, mas a ideia é criar um layout várias linhas, em que há:

  • um texto na primeira linha (já lá está, é o hello world);
  • um texto e uma caixa de entrada na segunda linha (lado a lado);
  • um botão na terceira linha (o botão é suposto ocupar toda a largura do écrã).


Bem, o texto do hello world já está no sítio, por isso nem lhe mexemos por enquanto.
Com o grupo "Form widgets" selecionado na palete, basta arrastar um TextView para a área do editor gráfico para criar a respetiva área de texto. Um TextView é o que noutros ambiente se chamaria uma Label (ou JLabel). É um texto estático, não interativo. A palette apresenta 4 TextView, a de tamanho normal (TextView), grande (Large), um pouco maior (Medium) e mais pequena (Small). Para este try escolhemos o que nos apetecer no momento. É claro que depois de introduzir a TextView lhe podemos mudar o tamanho (e mais uma tonelada de outras propriedades), mas vamos KISS e usar só o que está na palette.

Agora adicionamos o campo de entrada de texto. Esses campos estão no grupos Text Fields da palette. Há muito tipos, para texto, números, datas, passwords, etc. Escolhemos logo o primeiro e arrastamos para o editor gráfico. O campo de texto fica por baixo (ou por cima, depende de onde o largarmos) do TextView, mas nós queremos que fique ao lado. Não vale a penas arrastar mais, estamos a colocar os elementos dentro de um layout vertical, por isso ficam sempre na vertical. Temos de adicionar um layout horizontal. Estão no grupo Layouts.
Ao arrastar um LinearLayout horizontal, cria-se uma zona retangular vazia. Arrastamos agora o TextView e o Text Field para dentro deste retângulo. Por arrastamento é possível controlar qual fica à esquerda e à direita (prestar atenção às linhas amarelas que aparecem). O aspeto não fica muito bom (o texto deve ficar muito apertado), mas já vamos tratar disso a seguir.

Pro fim arrastamos um botão (está nos Form Widgets, há botões normais e pequenos) para baixo do LinearLayout horizontal. Mas o botão não ocupa a largura toda do écrã. Logo acima da pré-visualização do aspeto gráfico da atividade há uma série de botões. Com o botão selecionado vemos os seguintes:
Os dois primeiros controlam o tipo de layout (vertical ou horizontal) em que o elemento atual (neste caso o botão) está inserido. O terceiro e quarto controlam se o botão ocupa a largura/altura completa do écrã. Clicamos no terceiro. Os restantes botões controlam outras propriedades mais comuns do botão. Mais uma vez, estas propriedades podem ser alteradas na lista de propriedades do botão, esta barra de ferramentas é apenas um atalho para as propriedades mais comuns.

O aspeto da segunda linha (a que tem a TextView e o Text Field) também se pode melhorar com este botão. Provavelmente o melhor é desligar esta opção nos dois widgets.

Agora vamos tratar das strings.
Vamos supor que o campo de texto é para escrever o nosso nome e que, portanto, a TextView à esquerda deve ter a string "Nome".
Ao clicar nesta TextView vemos no Outline que é selecionado o "textView1". É o nome do objeto associada ao widget. Fazendo click direto sobre a TextView (ou sobre o seu identificador no Outline) aparece um menu de contexto. Precisamos da primeira opção, Edit Text...
Aparece uma caixa de diálogo com as strings definidas para a nossa aplicação. Por enquanto devem lá estar duas. Vamos criar uma terceira em New String... Em String colocamos o que queremos que apareça no écrã, neste caso "Nome" (sem aspas). Em New R.string colocamos o identificador que vai identificar este texto, por exemplo tvName (o tv é de TextView, mas é claro que se pode escolher outra coisa). Há mais uma série de propriedades que se podem editar, mas não lhes vamos mexer.
Depois de clicar em Ok, se formos espreitar ao ficheiro res/values/strings.xml, já lá está a nossa string.
Vamos agora editar o texto do botão. Click direito e Edit Text... Vamos criar uma nova string com o texto Ok e o id btOk.

Se queremos mudar o texto do "Hello World...", temos de ir ao strings.xml e alterar lá o valor da string.
Podemos agora correr o projeto.

Não faz absolutamente nada, mas está mais bonito.

sábado, 21 de abril de 2012

Programar para Android - 02


Um programa ainda mais simples.

Vamos fazer um programa para Android ainda mais simples que o "Hello World". O programa mais simples possível, nem sequer uma mensagem apresenta, limita-se somente a existir.
Criamos um novo projeto, chamemos-lhe Try00.
O Eclipse faz o favor de preparar tudo e de nos apresentar já feito um programa com uma atividade que mostra a mensagem "Hello World, Try00Activity!", mas queremos ainda menos. Abrimos o ficheiro de código e apagamos a parte relativa ao método onCreate, ficando apenas:


package pt.omeusite.try00;


import android.app.Activity;


public class Try0Activity extends Activity {
}

Também se retirou uma linha de import, que passou a deixar de ser necessária.

E cá está, o mais simples programa para Android, que não faz absolutamente nada!
Mas a mensagem "Hello World, Try00Activity!" que era apresentada antes tem de estar armazenada em algum lado. No código que apagamos não estava lá essa string, por isso onde andará ela?

Uma string é um recurso e todos os recursos estão na diretoria res. Dentro dela há várias subdiretorias, incluindo uma values e se abrirmos esta está lá uma ficheiro strings.xml. Ao abrir este strings.xml o Eclipse apresenta uma interface bonitinha que nos permite adicionar, remover, editar e ordenar vários elementos (strings, cores, etc). Podemos também ver o ficheiro em toda a sua glória XML clicando no separador na base da janela, mas a vista de recursos é mais civilizada. De momento devem aparecer duas strings uma hello e outra app_name. A app_name contém o nome da aplicação (Try0) mas podemos mudar para o que quisermos. A hello tem a nossa mensagem de hello world. Como apagamos o código vamos também apagar a string.
Se tentarmos correr agora o projeto, vai dar erro. Há um erro no ficheiro res/layout/main.xml.
Temos de ir lá editar este ficheiro. Este é outro XML muito importante e que controla o aspeto gráfico da atividade. Podemos ver e editar o XML diretamente, mas a interface gráfica apresentada pelo Eclipse é mais simples. O que acontece é que este main.xml tem uma referência à string hello que apagamos. A referência tem o aspeto @string/hello, que significa basicamente "vai aos recursos e procura no ficheiro das strings por uma com o nome hello". Temos de apagar esta referência (por curiosidade podemos dar uma olhadela ao main.xml antes e depois de apagar o @string/hello, para ver as diferenças).
Agora sim temos uma Activity que apenas mostra o nome da atividade, sem nada lá dentro.
Para mudar o nome da atividade basta mudar a string app_name em res/values/strings.xml.
Sempre que usarmos uma string numa aplicação podemos escrevê-la diretamente no meio do nosso código, mas é melhor colocar todas as strings no ficheiro strings.xml (dando um ID único a cada uma, claro) e depois usar referências a essas strings no nosso código. Facilita em muito o processo de tradução da aplicação e faz uma separação entre dados (strings) e código, o que é sempre positivo.

sexta-feira, 20 de abril de 2012

Programar para Android - 01


Hello Wordl!

O clássico "Hello World" é muito simples de fazer em Android, é mais difícil é de explicar.
O Android está pensado para ser usado com uma interface gráfica, por isso apesar de ser possível escrever para a consola, é muito mais fácil usar os widgets gráficos.
Para criar um novo projeto: File » New » Project... e escolher Android Project.

  • Next, dar um nome ao projeto, por exemplo Hello World
  • Next, escolher o alvo (target), ou seja a versão de Android
  • Next, a maior parte dos campos já tem preenchidos os valores pré-definidos que são normalmente "seguros", mas o Eclipse insiste em que indiquemos manualmente o packagename. O packagename é um nome constituído apenas por caracteres alfanuméricos e . (ponto final) que identifica o nosso projeto. Este identificador deve ser único, ou seja, não pode (deve) haver em todo o mundo nenhum outro projeto Android com o mesmo nome. Tipicamente usa-se o nome de domínio (admitindo que o programador tem um domínio) invertido adicionando o nome do projeto no fim. Ou seja, se o programador possuir o domínio "omeusite.pt" deverá colocar no packagename pt.omeusite.helloworld. Este nome irá identificar a aplicação se e quando for colocada na Android store, por isso a insistência em que seja um nome único.
  • Ao clicar em Finish é criado o projeto.

E já está pronto o programa Hello World. Para correr basta clicar no botão para correr a aplicação (ou Ctrl+F11). O AVD que tiver sido escolhido é lançado e a aplicação é automaticamente instalada e executada.

Olhando para o projeto no Eclipse vemos que foram criadas uma série de pastas e ficheiros. Não houve necessidade de editar manualmente nenhum desses ficheiros para criar o Hello World e grande parte deles nem devem sequer nunca ser tocados por mãos humanas.
Nas diretorias existem a:

  • src: Aqui estão as fontes do nosso projeto, as classes e packages que criarmos vão todas para aqui. 
  • Android*: Pode haver várias diretorias destas, dependendo do target escolhido, são as libraries da API.
  • gen: Ficheiros gerados pelo compilador, aqui aparecem ficheiros .java gerados automaticamente, ou seja NÃO MEXER.
  • bin: Ficheiros binários gerados pelo compilador, é aqui que aparecem os ficheiros .dex e .apk
  • res: Recursos, podem ser strings, imagens, documentos, whatever e muitos ficheiros XML. O compilador empacota todos os recursos nesta diretoria para serem facilmente acedidos de dentro da aplicação (com um objeto chamado R).
  • assets: São também recursos, mas não são "empacotados" pelo compilador, pelo que o acesso é mais trabalhoso. São usados quando é necessário usar dados em estado raw, ou seja, não pré-preparados pelo compilador. Na prática é pouco usado.
O Android NÃO corre código Java. Android usa um subconjunto da API Java (com algumas adições próprias). As aplicações Java do Android são compiladas normalmente para ficheiros .class (com o compilador Java) e estes ficheiros são de seguida novamente compilados para uma máquina Dalvik. A Dalvik é uma máquina virtual (semelhante ao Java, mas não é a mesma coisa) que está otimizada para dispositivos lentos e com recursos limitados. Os ficheiros .class são convertidos então em ficheiros .dex (Dalvik EXecutables) e empacotados juntamente com todos os recursos (imagens, sons, texto, etc) em ficheiros .apk (Android PacKage). Este ficheiro .apk é então enviado para o dispositivo (real ou virtual) que se encarrega de o descomprimir e colocar todos os ficheiros nos sítios certos, ficando a aplicação disponível para ser executada.
De uma forma simplista podemos pensar numa aplicação Android como:
.java -» .class -» .dex -» .apk

Observando o código da activity aparece algo como:

package pt.omeusite.helloworld;

import android.app.Activity;
import android.os.Bundle;

public class helloworldActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

A string "Hello World!" não aparece em lado nenhum! Como raios é que vai ter ao écrã do dispositivo? E de onde é que saiu aquele R?
Respostas no próximo capítulo.

Programar para Android - 00


Instalar o ambiente.

A melhor forma de programa para Android é usar um ambiente com Eclipse+JDK+Android SDK+ADT. É possível criá-lo tanto em Windows como em Linux ou Mac.

1. Fazer o download do eclipse


O Eclipse (http://www.eclipse.org/) é um ambiente de desenvolvimento para Java/C/C++/PHP/Whatever. Tem umas mil versões diferentes, a que interessa para este caso é a Classic. As outras versões também servem, mas iriam trazer módulos desnecessários (http://www.eclipse.org/downloads/).
Depois de fazer o download da versão certa para o sistema operativo certo, basta descomprimir o ficheiro. Não é necessário fazer a instalação, o Eclipse corre a partir da diretoria onde for descomprimido. Provavelmente será conveniente criar um atalho no Desktop para iniciar o Eclipse.

2. Instalar o JDK


O Java Development Kit (JDK) pode ser obtido em http://www.oracle.com/technetwork/java/javase/downloads/index.html. Fazer o download da versão pretendida para o sistema operativo. O Java Runtime Environmet (JRE) não é suficiente, é mesmo necessário o JDK.
No Ubuntu basta fazer algo tipo sudo apt-get install sun-java6-jdk, ou algo semelhante.

3. Obter o Android SDK


O Android Software Development Kit pode ser obtido em http://developer.android.com/sdk/index.html.
A versão Windows tem um instalador, mas basta descomprimir o ficheiro com o SDK. Lembrar onde estão os ficheiros descomprimidos, vão ser precisos mais tarde.

4. Obter o ADT


O Android Development Tools (ADT) é um plugin para Eclipse que permite utilizar o SDK de forma mais fácil. Não é obrigatória a sua instalação, mas é altamente recomendado.
A instalação faz-se no próprio Eclipse, em Help » Install new software...
Clicar em Add... e introduzir o endereço:
https://dl-ssl.google.com/android/eclipse/
Após alguns segundos aparece uma lista de pacotes. Selecionar todos os pacotes (basta selecionar o Developer Tools e são todos automaticamente selecionados), clicar em Next e novamente em Next. Aceitar as licenças e Finish. O Eclipse vai fazer o download e instalar os componentes. Pode aparecer um aviso sobre conteúdo não assinado. No final é preciso reiniciar o Eclipse. Ao reiniciar o Eclipse vai pedir a localização do SDK que descomprimimos no ponto anterior. Após isso o Eclipse faz mais alguns downloads. É preciso aceitar mais algumas licenças de utilização e fazer mais alguns downloads.

5. Configurando


Para instalar outras versões da API do Android, documentação, exemplos, etc, ir a Window » Android SDK Manager.
Aconselha-se a instalação de pelo menos o SDK da versão 2.1, pois a maior parte dos dispositivos no mercado são compatíveis com essa versão.
Para correr um programa feito no Eclipse numa máquina virtual Android é preciso primeiro criar uma máquina Android com o Android Virtual Device Manager (AVD). Ao criar uma máquina virtual especificamos as suas características (ecrã, disco SD, GPS, ...). Para isso ir a Window » AVD Manager. O AVD Manager também permite lançar o emulador. O boot da máquina virtual demora bastante tempo, por isso convém não a desligar (shutdown) depois de arrancar.

6. Fim


E pronto, só falta mesmo aprender a programar para Android.

quinta-feira, 1 de março de 2012

Ubuntu terminal server

O linux sempre foi capaz de suportar sessões remotas, tanto na CLI como na interface gráfica, pois está completamente construído à volta da arquitetura cliente-servidor.
Para iniciar uma sessão remota completamente encriptada através de CLI basta usar o ssh, para poder usar aplicações gráficas através da ligação ssh basta adicionar a opção -X ao ssh. O servidor X pode ser configurado para aceitar sessões remotas (ou seja, o desktop completo e não apenas aplicações individuais) através do XDMCP.
Desde que fiquemos sempre no mundo linux (ou OSX) funciona tudo, mas se queremos ligar a partir de uma máquina Windows a uma máquina linux estamos mais limitados. Existem alguns clientes X para Windows: Cygwin/X, Xming, WeirdX, eXceed, etc. Alguns são open source, outros são proprietários.
O protocolo NX vai um passo mais à frente e permite usar várias técnicas (cache, compressão de dados) para acelerar o processo, permitindo usar sessões remotas mesmo através de ligações lentas.
A empresa NoMachine disponibiliza clientes gratuitos para Windows, Linux, MacOS e Solaris. O núcleo das aplicações NX é open source, mas algumas das aplicações disponibilizadas pela NoMachines são pagas. Há o projeo FreeNX que fornece um servidor NX completamente open source e ainda a Google disponibiliza um servidor compatível com o protocolo NX chamado NeatX.
Há então 3 alternativas para criar um servidor NX: o servidor da NoMachines, FreeNX e NeatX.

Servidor da NoMachines
Na máquina servidora é preciso instalar o pacote cliente (nxclient), o node (nxnode) e finalmente o servidor (nxserver). Fica imediatamente a funcionar, mas está limitado a 2 utilizadores, mesmo que não estejam ligados em simultâneo.

FreeNX
Basta seguir este guião:
https://help.ubuntu.com/community/FreeNX

NeatX
Vamos então instalar o servidor NeatX numa máquina com Ubuntu (lucid).
sudo apt-get install python-software-properties
sudo add-apt-repository ppa:freenx-team

sudo apt-get update
sudo apt-get install neatx-server

Nos três casos, na máquina cliente (Windows, linux, Mac ou Solaris), basta ir a http://www.nomachine.com/download.php e fazer o download do cliente respetivo.

x2go
O projeto x2go pretende atingir o mesmo objetivo, mas é completamente open source. Usa as bibliotecas do NX, pelo que o seu desempenho deverá ser equivalente.
Por enquanto ainda não está num estado muito maturo, mas é um projeto a manter debaixo de olho.
http://www.x2go.org/

WinSwitch
Esta aplicação permite partilhar janelas de aplicações entre diferentes sistemas. Por exemplo inicia-se o OpenOffice no linux e pode enviar-se a janela para um computador Windows ou Mac ligado a esse servidor linux. Não consegui partilhar aplicações Windows para o Linux, mas suponho que seja possível. Mais um projeto a manter debaixo de olho.
http://winswitch.org/

Referências
http://www.ubuntugeek.com/how-to-install-neatx-similar-to-freenx-server-on-ubuntu-10-04-lucid-lynx.html
Mais leituras
http://diznix.com/articles/remote-x-connecting-to-linux-from-windows/