domingo, 22 de abril de 2012

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/

segunda-feira, 27 de fevereiro de 2012

XDMCP

O XDMCP (X Display Manager Control(?) Protocol(?)) permite fazer o login remoto numa máquina linux, como o telnet, mas em modo gráfico. Digo como o telnet e não 'como o ssh' porque o XDMCP é inerentemente inseguro. Uma forma de o tornar seguro é usar um túnel ssh para fazer a ligação. O XDMCP usa o porto UDP 177.
Para funcionar é preciso um gestor de login (login manager) que suporte XDMCP. Apenas o XDM e o KDM suportam XDMCP (que eu tenha descoberto). O GDM removeu o suporte para XDMCP.
Para usar o XDMCP com KDM é preciso:
1. Primeiro que tudo, instalar o KDM e torná-lo o gestor de login pré-definido
Em Ubuntu:
sudo apt-get install kdm
E para redefinir o KDM como gestor por defeito:
sudo dpkg-reconfigure kdm
2. Editar o kdmrc e acrescentar as linhas:
[xdmcp]
Enable=true

3. Editar o Xaccess e descomentar a linha (basta apagar o primeiro '#')
# * # any host can get a login window
Não é a configuração mais segura, mas funciona.
4. Reiniciar o kdm (ou o computador).

sábado, 25 de fevereiro de 2012

Amenizando o Debian

Um conjunto de scripts e dicas para amenizar um pouco o Debian.
Devivo à estrita aderência ao ideal open source o Debian está privado da utilização de algum software, mas como utilizador individual posso instalar o que quiser no Debian...

O equivalente Debian ao ubuntu-restricted-extras

Ligar o contrib e o non-free no sources.list
Adicionar ao sources.list:

deb http://deb-multimedia.org squeeze main non-free

Adicionar a chave do debian-multimedia


wget http://deb-multimedia.org/gpgkey.pub -O - | apt-key add - && apt-get install deb-multimedia-keyring

Adicionar os pacotes de interesse:


apt-get install acroread ffmpeg flashplugin-nonfree libcurl3 flashplugin-nonfree-extrasound freepats gstreamer0.10-ffmpeg gstreamer0.10-plugins-bad gstreamer0.10-plugins-ugly sun-java6-jre sun-java6-plugin sun-java6-fonts libaccess-bridge-java libavcodec52 libavformat52 libcdaudio1 libdc1394-22 libdvdnav4 libdvdread4 libfftw3-3 libgif4 libid3tag0 libiptcdata0 libmjpegtools-1.9 libmms0 libmp4v2-0 libmpeg2-4 libmusicbrainz4c2a libneon27-gnutls libofa0 libopenspc0 libpostproc51 libsidplay1 libsndfile1 libsoundtouch1c2 libswscale0 libwildmidi1 openjdk-6-jre openjdk-6-jre-headless openjdk-6-jre-lib rhino ttf-arphic-uming ttf-baekmuk ttf-bengali-fonts ttf-devanagari-fonts ttf-gujarati-fonts ttf-indic-fonts ttf-kannada-fonts ttf-kochi-gothic ttf-liberation ttf-malayalam-fonts ttf-mscorefonts-installer ttf-oriya-fonts ttf-punjabi-fonts ttf-sazanami-mincho ttf-tamil-fonts ttf-telugu-fonts tzdata-java unrar

À medida que sairem novas versões destes pacotes será necessário corrigir a numeração de alguns pacotes.

Referências
http://ubuntuforums.org/showthread.php?p=6019449
http://forums.debian.net/viewtopic.php?f=20&t=67013